背景监控大屏用 Nginx 反代两个 Flask 实例开了 proxy_cache 想减轻后端压力。配置看起来没问题响应头也有 X-Cache-Status。但连续 curl 十次结果全是10 MISS缓存目录里只有 1 个文件基本等于没生效。想做到让缓存真正命中。原因第一步看响应头$curl-k-s-D--o/dev/null https://example.com:8443/|grep-icache cache-control: no-cache x-cache-status: MISS第二步直连后端看原始响应$curl-s-D--o/dev/null http://127.0.0.1:5001/ HTTP/1.1200OK Cache-Control: no-cache根因后端返回了 Cache-Control: no-cache。Nginx 默认尊重上游的 Cache-Control——上游说别缓存Nginx 就真不缓存。就像你在货架上贴了「欢迎放商品」但供应商送货时贴了张纸条「此商品不得上架」。店员只能照办货架空着。解决一、让 Nginx 忽略上游的 Cache-Controllocation /{proxy_cache my_cache;# 关键忽略上游的 Cache-Control 和 Expires proxy_ignore_headers Cache-Control Expires;proxy_cache_valid 200 302 5m;proxy_cache_valid 404 1m;add_header X-Cache-Status $upstream_cache_status always;proxy_passhttp://backend_cluster;}只忽略这两个别一股脑全忽略响应头是否忽略原因Cache-Control✅ 忽略上游默认带 no-cache会阻止缓存Expires✅ 忽略和 Cache-Control 配套Set-Cookie❌ 不忽略忽略会串号Vary❌ 不忽略忽略会破坏多版本缓存二、固定 proxy_cache_keyproxy_cache_key $scheme$request_method$host$request_uri;排除 $args 和 cookie 干扰同一个 URL 共用一份缓存。副作用如果页面按 cookie 分版本就不能这么做。我这里是内部大屏可以接受。三、加 proxy_cache_lock 防击穿proxy_cache_lock on; proxy_cache_lock_timeout 5s;货架上的牛奶卖完了10 个顾客同时冲进仓库。加锁 只让第一个人进后面的人等在门口。四、后端抖了用过期缓存顶一下可选proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504; proxy_cache_background_update on;完整配置location /{proxy_cache my_cache;proxy_cache_key$scheme$request_method$host$request_uri;proxy_ignore_headers Cache-Control Expires;proxy_cache_valid 200 302 5m;proxy_cache_valid 404 1m;proxy_cache_lock on;proxy_cache_lock_timeout 5s;proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;proxy_cache_background_update on;add_header X-Cache-Status $upstream_cache_status always;proxy_passhttp://backend_cluster;}sudonginx-tsudosystemctl reload nginx验证效果$foriin{1..10};docurl-k-s-o/dev/null-D- https://example.com:8443/\|awk-F: tolower($1)x-cache-status{print $2}sleep0.2done|sort|uniq-c1MISS9HIT9 HIT / 1 MISS命中率 90%。项目优化前优化后命中率0%~90%回源次数10 次101响应时间取决于后端命中时几乎为 0三个坑坑 1以为开了 proxy_cache 就会缓存上游可以返回这些头让 Nginx 放弃缓存响应头含义Cache-Control: no-cache每次都校验Cache-Control: no-store完全禁止Cache-Control: private只允许浏览器缓存Set-Cookie默认不缓存坑 2proxy_cache_key 忘了固定默认 key 里如果带了 ?timestampxxx 或 cookie每次请求都是新 key缓存命中率永远上不去。正确做法显式写 proxy_cache_key只留真正影响内容的部分。坑 3X-Cache-Status 加了但日志里看不到add_header 只是返回给客户端日志统计要单独配# 在 http 块里定义必须放 conf.d/不能放 server log_format cache_tsv $time_iso8601\t$host\t$request_method\t$request_uri\t$status\t$upstream_cache_status; # 在 server 块里启用 server { listen 8081; access_log /var/log/nginx/dashboard_cache.log cache_tsv; }注意\t 是字面反斜杠 tNginx 自己解释成制表符。写 heredoc 时用单引号 ‘EOF’否则 shell 会展开。还有只有配了 proxy_cache 的那层 Nginx 才有 HIT/MISS外层反代的 $upstream_cache_status 是 -。生活小插曲最近我开始写小说了名字就不说了等有一定流量再宣传。