我必须在一个非常慢的API前放置一个缓存服务。 api响应大约40秒,这对我的用户来说太长了。我想使用像Varnish这样的东西来缓存响应。
这是我的问题:
当缓存服务第一次被点击时,从上游API获取响应大约需要40秒。所有连续请求将直接从缓存提供。当缓存TTL已过期时,缓存服务必须再次命中缓慢的API并等待40秒,这是不可接受的。有没有办法通过做某种异步后台缓存更新来避免它?如果是这样,Varnish能做到吗?
为简单起见,我们假设所有客户端请求都是相同的。
如果缓存服务每秒被攻击数百次,情况实际上要糟糕得多。等待刷新缓存的40秒长将排队数千个客户端请求,这可能导致不同类型的问题,包括丢弃连接。我假设Varnish足够智能,它只会触发上游API调用一次并将其他请求排队,直到它得到响应。
Varnish或其他替代方案是否保留最后一次的好副本?如果我的慢速API已经关闭并且根本没有响应,那么即使它已经过期,是否可以从缓存服务LKGC?
实现这一切的最佳软件是什么?
答案 0 :(得分:1)
Varnish通过宽限模式绝对支持此功能。你需要一点VCL code magic to enable grace mode。这就是它:
因此,只有初始请求会很慢。客户将获得刷新请求,不会有任何延迟。
基本上,您希望将“健康的后端宽限期”设置为后端生成响应所需的最长时间。例如:
sub vcl_hit {
if (obj.ttl >= 0s) {
# normal hit
return (deliver);
}
# We have no fresh fish. Lets look at the stale ones.
if (std.healthy(req.backend_hint)) {
# Backend is healthy. Limit age to 45s.
if (obj.ttl + 45s > 0s) {
set req.http.grace = "normal(limited)";
return (deliver);
} else {
# No candidate for grace. Fetch a fresh object.
return(fetch);
}
} else {
# backend is sick - use full grace
if (obj.ttl + obj.grace > 0s) {
set req.http.grace = "full";
return (deliver);
} else {
# no graced object.
return (fetch);
}
}
}
在这个例子中,我将它设置为45秒。这样可以确保缓慢的API请求可能需要40秒。