必须启用 proxy_intercept_errors on 和 error_page 404 = @handle_404,再于 @handle_404 中配置 proxy_cache 与 proxy_cache_valid 200 5s,返回静态 /404.html,方可实现短周期 404 防刷缓存。

直接在 proxy_cache_valid 中写 404 5s 并不能让 Nginx 自动缓存 404 页面——它默认跳过所有非 2xx/3xx 响应。要实现对 404 的动态缓存防探测,核心是“让 Nginx 主动接管并缓存‘不存在’这个结果”,而不是等后端返回再决定是否缓存。
必须启用错误拦截与内部重写
后端返回的原始 404 不会进入缓存流程,除非你告诉 Nginx:“把它当作可处理、可缓存的响应”。这需要两步配合:
-
开启拦截:
proxy_intercept_errors on;—— 启用后,Nginx 才会捕获上游返回的 404,而不是直接透传 -
内部重定向到可缓存路径:
error_page 404 = @handle_404;—— 注意等号,表示不改变状态码,但把响应生成逻辑交由@handle_404location 处理
为 @handle_404 配置轻量缓存策略
这个命名 location 是关键执行单元,它应返回一个极简、可缓存的响应(如纯文本或小体积 HTML),并明确启用缓存:
-
使用独立缓存区:比如
proxy_cache 404_cache;,避免和业务缓存混用 -
只缓存 200 响应:
proxy_cache_valid 200 5s;—— 因为@handle_404返回的是 200 状态码(内容是自定义 404 页面),这才是真正被缓存的对象 -
返回静态文件最稳妥:
root /usr/share/nginx/html; try_files /404.html =404;,确保/404.html文件存在且权限正确
精准控制缓存键与自动清理
恶意探测常带随机参数(如 ?t=123、?id=abc),若缓存键不区分参数,会导致不同请求相互覆盖或漏防:
-
带参缓存键示例:
proxy_cache_key "$scheme$request_method$host$request_uri$args"; -
防止缓存堆积:在
proxy_cache_path中设置inactive=10s;,确保未被重复访问的 404 缓存项 10 秒后自动释放
增强容错与防雪崩能力
短时缓存本身有窗口期风险——刚过期时大量请求同时打向后端。可叠加 stale 机制兜底:
-
proxy_cache_use_stale error timeout http_404 updating;—— 即使缓存失效,只要后端返回 404 或超时,仍可返回旧缓存 -
proxy_cache_background_update on;—— 在后台悄悄刷新缓存,不影响用户响应











