源站响应码变更时无需重启清除NGINX指定请求缓存的方法
NGINX仅缓存404场景下的持久stale响应解决方案
现有配置proxy_cache_valid 404 1m; proxy_cache_valid any 0;存在逻辑缺陷:proxy_cache_valid any 0不会阻止未过期的404缓存被返回,当源站对应路径从404切换为200时,NGINX不会主动回源校验已存的404缓存条目,因此会持续返回过期的404内容。
以下是无需重启NGINX实例即可解决问题的可行方案:
方案1:使用开源第三方ngx_cache_purge模块实现精确缓存删除
多数人会混淆商业版内置的proxy_cache_purge指令和开源第三方模块ngx_cache_purge,后者完全免费,支持开源版NGINX实现指定URL缓存清理:
- 先执行
nginx -V检查现有编译参数,若输出中包含--add-module=*/ngx_cache_purge,说明模块已预装,直接写配置即可;若未预装,只需要重新编译NGINX替换二进制文件,执行nginx -s reload平滑升级,不需要中断服务、不需要全量重启。 - 在对应server块中新增清理路由配置:
location ~ /purge(/.*) { allow 127.0.0.1; allow 你的运维网段IP; deny all; proxy_cache_purge main_cache $scheme$proxy_host$1$is_args$args; }
- 清理方式:需要删除
example.com/page_A的缓存时,本机发起请求到http://127.0.0.1/purge/page_A,返回200即代表缓存清理成功,后续用户请求会自动回源拉取最新的200响应。
方案2:调整缓存校验逻辑从根源避免stale 404问题(无需额外模块)
如果不想安装第三方模块,可以直接调整缓存规则,让NGINX返回404缓存前强制校验源站状态,从根源避免旧404缓存持续返回的问题:
proxy_cache_path /nginx/cache keys_zone=main_cache:48m levels=1:2 inactive=24h max_size=10g use_temp_path=off; # 新增以下配置 proxy_cache_key "$scheme$proxy_host$request_uri"; proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; # 仅源站故障时才返回stale缓存,源站正常时优先回源 proxy_cache_revalidate on; proxy_cache_valid 404 1m; proxy_cache_valid 200 0s; # 明确配置200响应不缓存 add_header X-Cache-Status $upstream_cache_status; # 增加响应头方便排查缓存命中状态
配置完成后执行nginx -s reload重载即可生效,后续源站从404切换为200时,NGINX会自动识别新响应,不会持续返回旧缓存。
方案3:手动删除缓存文件(临时应急使用)
如果是临时应急处理,不需要安装模块、不需要重载配置,可以直接计算缓存文件路径手动删除:
- 按照你当前配置的默认缓存key规则,待清理URL
http://example.com/page_A对应的key字符串为httpexample.com/page_A - 执行命令计算key的MD5值:
echo -n "httpexample.com/page_A" | md5sum - 按照
levels=1:2的规则拼接缓存文件路径:取MD5值最后1位为一级目录,倒数第2-3位为二级目录,剩余字符串为文件名,例如MD5值为789abcd1234efgh5678,对应路径为/nginx/cache/8/78/789abcd1234efgh5678 - 直接删除对应文件即可,无需重启NGINX,后续请求会自动回源拉取最新内容。
注意:手动删除文件的方式操作效率低,仅适合单次应急处理,频繁清理缓存建议使用前两种方案。
内容的提问来源于stack exchange,提问作者Jinks
相关产品推荐
相关产品推荐

