Fra*_*ine 2 caching varnish varnish-vcl
我有一个位于 Varnish 后面的 Plone 网站。除了一件事外,一切正常。
这是一个动态网站,因此会不时有新内容。场景如下:
我有一个显示项目列表的页面。此页面已被缓存。所以我通过某种形式添加了另一个项目,并返回到同一页面,但没有显示新项目。这是因为显示的页面来自缓存并且仍在其 TTL 内。
如何确保在提交新项目时,从缓存中清除该页面,并显示来自后端服务器的带有新项目的新页面?
我的简单VCL如图所示:
backend default {
.host = "127.0.0.1";
.port = "8080";
}
sub vcl_recv {
if (req.request != "GET" && req.request != "HEAD") {
# We only deal with GET and HEAD by default
return (pass);
}
# remove unnecessary cookies
if (req.http.cookie ~ "wc.cookiecredentials|Path|Domain") {
# found wc.cookiecredentials in request, passing to backend server
return (lookup);
} else {
unset req.http.cookie;
}
}
sub vcl_fetch {
#unset beresp.http.Set-Cookie;
set beresp.ttl = 12h;
return(deliver);
}
# Routine used to determine the cache key if storing/retrieving a cached page.
sub vcl_hash {
# Do NOT use this unless you want to store per-user caches.
if (req.http.Cookie) {
set req.hash += req.http.Cookie;
}
}
sub vcl_deliver {
# send some handy statistics back, useful for checking cache
if (obj.hits > 0) {
set resp.http.X-Cache-Action = "HIT";
set resp.http.X-Cache-Hits = obj.hits;
} else {
set resp.http.X-Cache-Action = "MISS";
}
}
Run Code Online (Sandbox Code Playgroud)
或者说白了,当我收到 POST 请求时,如何清除或清除域的整个缓存?
为此,您需要自定义 Varnish VCL 来处理PURGE请求和 Plone CMS,以便在内容更改时向 Varnish 发出清除请求。
Plone Developer Documentation 有关于在Plone 中使用 Varnish 的非常好的和详尽的文档。您可以根据自己的特定需求进行调整。
文档中的示例解释了如何在 VCL 中创建自定义 ACL 和正则表达式清除处理,然后如何在 Plone 中使用它来清除整个缓存。我已经从这里的示例中复制了 VCL 和 Plone 视图,以防它们在将来某个时候从 Plone 站点中删除:
acl purge {
"localhost";
# XXX: Add your local computer public IP here if you
# want to test the code against the production server
# from the development instance
}
...
sub vcl_recv {
...
# Allow PURGE requests clearing everything
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
# Purge for the current host using reg-ex from X-Purge-Regex header
purge("req.http.host == " req.http.host " && req.url ~ " req.http.X-Purge-Regex);
error 200 "Purged.";
}
}
Run Code Online (Sandbox Code Playgroud)
然后为 Plone 创建一个自定义视图,用于向PURGEVarnish发出请求:
import requests
from Products.CMFCore.interfaces import ISiteRoot
from five import grok
from requests.models import Request
class Purge(grok.CodeView):
"""
Purge upstream cache from all entries.
This is ideal to hook up for admins e.g. through portal_actions menu.
You can access it as admin::
http://site.com/@@purge
"""
grok.context(ISiteRoot)
# Onlyl site admins can use this
grok.require("cmf.ManagePortal")
def render(self):
"""
Call the parent cache using Requets Python library and issue PURGE command for all URLs.
Pipe through the response as is.
"""
# This is the root URL which will be purged
# - you might want to have different value here if
# your site has different URLs for manage and themed versions
site_url = self.context.portal_url() + "/"
headers = {
# Match all pages
"X-Purge-Regex" : ".*"
}
resp = requests.request("PURGE", site_url + "*", headers=headers)
self.request.response["Content-type"] = "text/plain"
text = []
text.append("HTTP " + str(resp.status_code))
# Dump response headers as is to the Plone user,
# so he/she can diagnose the problem
for key, value in resp.headers.items():
text.append(str(key) + ": " + str(value))
# Add payload message from the server (if any)
if hasattr(resp, "body"):
text.append(str(resp.body))
Run Code Online (Sandbox Code Playgroud)
如前所述,这只是根据需要清除整个缓存。我不是 Plone 方面的专家,因此我无法就如何将其调整为仅清除特定内容提供详细的答案。基本上,您需要确定在特定情况下需要清除哪些页面,然后调整上面的示例以在 Plone 中处理PURGE请求时自动向 Varnish发出请求POST。
单独在 VCL 中处理清除(即检测 POST 调用并根据这些调用清除内容)非常复杂。我相信在 Plone 中处理逻辑和清除会更有效。
更新:
如果您希望清除每个 上的整个缓存POST,可以按如下方式完成。
sub vcl_recv {
if ( req.request == "POST") {
ban("req.http.host == " + req.http.Host);
return(pass);
}
}
Run Code Online (Sandbox Code Playgroud)
现在每个POST请求都会导致缓存在同一主机名下的所有页面从缓存中清除。不过,我建议从长远来看,研究早期的解决方案。仅清除POST发生时实际需要清除的页面会更有效。
| 归档时间: |
|
| 查看次数: |
3299 次 |
| 最近记录: |