Nginx 反向代理缓存使用中有一个情况,当;
proxy_cache_background_update on;
proxy_cache_use_stale updating;
对于同一个 URL,如果一个响应来自上游并且具有 max-age,而所有其他响应都为 no-cache,那么 Nginx 将永远无法从这种情况中恢复。
想象一下这样的场景:
- 客户端 -> Nginx(MISS) -> 上游200(缓存控制:无缓存)
- 客户端 -> Nginx(MISS) -> 上游200(缓存控制:无缓存)
- 客户端 -> Nginx(MISS) -> 上游200(缓存控制:无缓存)
- 客户端 -> Nginx(MISS) -> 上游503(缓存控制:最大年龄=10)
- 客户端 -> Nginx (HIT,503,年龄:3)
- 客户端 -> Nginx (HIT,503,年龄:8岁)
- 客户端 -> Nginx (陈旧,503,年龄:13岁)->保利上游200 (缓存控制:无缓存)
- 客户端 -> Nginx (陈旧,503,年龄:18岁)->保利上游200 (缓存控制:无缓存)
- 客户端 -> Nginx (陈旧,503,年龄:23岁)->保利上游200 (缓存控制:无缓存)
- ... 客户看到503永恒
在上述场景中,上游发生了一次错误,并返回了 max-age(不幸的是,这种行为无法干预)。因为真正的 200 响应是 no-cache,所以它永远无法覆写STALE 503 并永远给出错误直到手动清除。
在网上找不到关于这种情况的任何信息,所以我在这里问。如何处理这个问题。我正在使用OpenResty因此我就可以访问 Nginx 开源模块和 Lua。
可能的解决方案和我的研究:
stale-if-error
Cache-Control 标头的扩展stale-while-revalidate
似乎确实解决了这个问题。不幸的是,上游标头不允许修改(而且在 Nginx 处理标头之前,没有办法像预期的那样以黑客方式插入这些标头)。使用 Lua 脚本手动设置 STALE 缓存的超时时间,并在超时后清除缓存。但如果标准/Nginx 提供了解决方案,我更愿意使用它。
添加第二个反向代理来添加标题
stale-if-error
并stale-while-revalidate
默认(我宁愿让问题存在,而不是这样做)。使用 Lua 跟踪缓存期限,如果超过则设置变量为 true,然后
proxy_cache_bypass
从 Nginx 中使用它。(有点灰色区域,执行顺序与内容阶段指令有关)