nginx proxy_cache 不缓存304响应,后端擅自返回304会导致502、缓存失效或状态错乱;排查需确认后端是否直发304及nginx日志中$upstream_status是否为304,并通过proxy_intercept_errors等配置兜底。

Nginx proxy_cache 本身不缓存 304 响应,也不会用它填充缓存条目。所谓“代理后端返回 304 导致缓存混乱”,本质是后端错误地直接向 Nginx 返回了 304,而 Nginx 拒绝处理该响应,进而引发 502、缓存失效或状态错乱。排查需聚焦“谁发了 304”和“Nginx 怎么反应”两个关键点。
确认后端是否擅自返回 304
这是根源性问题。Nginx 作为反向代理,不应接收上游的 304 —— 它没有原始资源副本,无法验证“未修改”。检查方式很直接:
- 用
curl -I http://your-api/endpoint绕过 Nginx 直连后端,看响应头中是否有HTTP/1.1 304 Not Modified - 在 Nginx access_log 中添加
$upstream_http_content_length和$upstream_status,观察是否出现304状态码及空 body(content-length: 0) - 查 error_log,搜索
upstream sent no valid HTTP/1.0 header或upstream prematurely closed connection,这是 Nginx 拒收 304 的典型报错
验证 Nginx 是否跳过了缓存逻辑
一旦后端返回 304,Nginx 会中断代理流程,既不写缓存,也不更新缓存元数据,相当于本次请求完全“脱轨”。表现就是:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
-
$upstream_cache_status日志字段大量为BYPASS或空值,而非MIS/HIT - 同一 URL 多次请求,Nginx 却始终回源,
proxy_cache_valid配置形同虚设 - 响应头中缺失
X-Cache-Status或显示MISS后紧接502,说明缓存根本没参与
强制后端回归 200 + 校验头规范
正确做法是让后端永远返回完整 200 响应,并附带可信的 Last-Modified 或强 ETag。Nginx 才能基于这些头自主判断是否生成 304:
- 后端关闭自动 304 机制(如 Express 的
res.set('ETag', ...)要保留,但禁用res.sendStatus(304)) - Nginx location 中启用协商:去掉
etag off和if_modified_since off,确保proxy_cache_use_stale和proxy_cache_revalidate按需开启 - 加日志辅助验证:
add_header X-Upstream-Status $upstream_status;,确认上游稳定返回 200
快速隔离与兜底配置
若短期内无法修改后端,可在 Nginx 层做防御性配置,避免 304 干扰整体缓存流:
- 在对应 location 中加入
proxy_intercept_errors on;和error_page 304 = 502;,把非法 304 统一转为可识别错误 - 用
proxy_hide_header ETag;和proxy_hide_header Last-Modified;清除后端可能误传的校验头,防止被误用于协商 - 对已知路径(如
/api/)显式关闭协商:etag off; if_modified_since off;,彻底切断 304 触发链










