我正在调查 Varnish 是否可以支持过时的内容,如RFC 5861. 为实现这一目标stale-while-revalidate
,stale-if-error
缓存指令我找到了一个 varnish 的示例实现v4和v5。
但在实施过程中存在两个问题:
- 第一:据报道它会干扰本机
stale-while-revalidate
(grace
)功能,请参阅问题 - 第二:varnish v6没有样品。
为了解决 v6 问题,其中return(miss)
被删除vcl_hit{}
,我尝试了建议的迁移升级指南:
sub try_stale_if_error {
if (obj.ttl < 0s && obj.ttl + obj.grace > 0s) {
if (req.restarts == 0) {
set req.http.sie-enabled = true;
return (restart);
} else {
set req.http.sie-abandon = true;
return (deliver);
}
}
}
sub vcl_recv {
if (req.restarts > 0 && req.http.sie-enabled) {
set req.hash_always_miss = true;
}
}
它有点起作用,但就我所知,它的作用仅仅比内置的更多grace
。stale-while-revialidate
是否有可能以规范所说的方式正确实现该功能,使得stale-while-revalidate
(obj.grace
)和stale-if-error
(可能使用obj.keep
)可以同时工作?
同样值得注意的是:Avmod stale
存在于名为“Varnish Cache Plus”
答案1
实现两者的唯一真正解决方案stale-if-error
是stale-while-revalidate
使用vmod_stale
清漆企业。
这是stale-while-revalidate
常规 VCL 中的实现,但它没有stale-while-revalidate
通过Cache-Control
标题设置的灵活性:
vcl 4.1;
import std;
backend default {
.host="localhost";
.port="8080";
.probe={
.url="/";
}
}
sub vcl_recv {
if (std.healthy(req.backend_hint)) {
set req.grace = 10s;
}
}
sub vcl_backend_response {
set beresp.http.sie = std.integer(regsub(beresp.http.Cache-Control,"^.*stale-if-error=([0-9]+).*$","\1"),0);
set beresp.grace = std.duration(beresp.http.sie + "s",beresp.grace);
}
此示例将宽限期设置为 的值Cache-Control: stale-if-error=...
。vcl_recv
如果服务器运行正常,我们可以限制此值,但宽限期值是硬编码的,不能来自Cache-Control: stale-while-revalidate=...
。
beresp.keep
在这种情况下将不起作用,因为它仅用于保留对象以进行同步重新验证,而 grace 可用于提供陈旧数据。
我们开发的原因vmod_stale
是为了重新武装对象并设置新的 TTL、宽限期和保留值。通过最初将保留值设置为非常高的数字,我们确保对象被保留,然后vmod_stale
可以重新武装它。
你的选择是要么使用我的穷人的stale-if-error
实现,要么升级到清漆企业。
关于 Varnish Enterprise 的附注
一个简单的方法来尝试清漆企业如果您有兴趣,可以在云基础架构上启动一个实例,而无需预付许可费用: