gpt4 book ai didi

caching - Varnish:POST 数据后清除缓存

转载 作者:行者123 更新时间:2023-12-03 17:45:46 28 4
gpt4 key购买 nike

我有一个位于 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";
}
}

或者说白了,当我收到 POST 请求时,如何清除或清除域的整个缓存?

最佳答案

要实现此目的,您需要自定义 Varnish VCL 来处理 PURGE 请求和 Plone CMS,以便在内容更改时向 Varnish 发出清除请求。

Plone 开发者文档在 using Varnish with Plone 上有非常好的和全面的文档。 。您可以根据您的具体需求进行调整。

文档中的示例解释了如何在 VCL 中创建自定义 ACL 和正则表达式清除处理,以及如何在 Plone 中使用它来清除整个缓存。我从此处的示例中复制了 VCL 和 Plone View ,以防万一它们将来某个时候从 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.";
}
}

然后,为 Plone 创建一个自定义 View ,用于向 Varnish 发出 PURGE 请求:

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))

如上所述,这只是根据需要清除整个缓存。我不是 Plone 方面的专家,因此我无法为您提供有关如何使其适应仅清除特定内容的详细答案。基本上,您需要确定在特定情况下需要清除哪些页面,然后调整上面的示例,以便在 Plone 中处理 POST 请求时自动向 Varnish 发出 PURGE 请求.

单独在 VCL 中处理清除(即检测 POST 调用并根据这些调用清除内容)相当复杂。我相信在 Plone 中处理逻辑和清除会更加有效。

更新:

如果您希望在每次POST 时清除整个缓存,可以按如下方式完成。

sub vcl_recv {
if ( req.request == "POST") {
ban("req.http.host == " + req.http.Host);
return(pass);
}
}

现在,每个 POST 请求都会导致在同一主机名下缓存的所有页面从缓存中清除。但从长远来看,我建议研究早期的解决方案。当 POST 发生时,仅清除实际需要清除的页面会更有效。

关于caching - Varnish:POST 数据后清除缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14518229/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com