如何把 Nginx 配置为缓存反向代理?
Nginx 缓存反代配置:proxy_cache_path 定义缓存区,proxy_cache 启用,proxy_cache_valid 按状态码设有效期;含完整配置示例、缓存键、绕过条件、清理与 FAQ。
两步:① http 块里用 proxy_cache_path 定义缓存存放路径和共享内存区;② 在 server/location 里 proxy_cache 引用该区域并设 proxy_cache_valid 有效期,同时照常 proxy_pass 到上游。 缓存命中后请求不再回源,上游压力和响应延迟都会显著下降。
完整配置示例
http {
# ① 定义缓存:磁盘路径、目录层级、内存索引区、上限、闲置清理
proxy_cache_path /var/cache/nginx
levels=1:2
keys_zone=my_cache:10m
max_size=10g
inactive=60m
use_temp_path=off;
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend:8080;
# ② 启用缓存
proxy_cache my_cache;
proxy_cache_valid 200 302 10m; # 成功与重定向缓存 10 分钟
proxy_cache_valid 404 1m; # 404 只缓存 1 分钟
# 让客户端知道是否命中(调试神器)
add_header X-Cache-Status $upstream_cache_status;
# 回源所需的头
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
关键参数解释
levels=1:2:磁盘上两级目录哈希,避免单目录文件过多。keys_zone=my_cache:10m:10MB 共享内存存缓存键,约可索引 8 万个条目。inactive=60m:60 分钟没被访问的缓存会被清理(不管是否过期)。$upstream_cache_status:HIT/MISS/BYPASS/EXPIRED,验证缓存行为的第一手资料。
常用进阶
# 带 Cookie 的请求不缓存(个性化页面必须加)
proxy_cache_bypass $http_cookie;
proxy_no_cache $http_cookie;
# 自定义缓存键(默认已含 scheme/host/uri)
proxy_cache_key "$scheme$host$request_uri";
# 上游挂了时用陈旧缓存兜底
proxy_cache_use_stale error timeout http_500 http_502;
# 同一资源并发回源只放行一个请求
proxy_cache_lock on;
缓存清理
- 整体清:直接删
/var/cache/nginx下内容再 reload。 - 精确清:需要
proxy_cache_purge(商业版或第三方模块),或给缓存键设计可预测的版本号(如 URL 里带?v=123)做"事实失效"。
观测云对照
缓存代理的价值要用命中率说话。把 Nginx 访问日志接入观测云,把 X-Cache-Status 也记进日志格式,就能在日志查看器里直接统计 HIT/MISS 比例、按 URI 找"缓存黑洞";再对回源带宽、上游 5xx 配监控告警,缓存配置失误(比如误缓存了登录接口)引发的异常流量能立刻看到。
常见问题(FAQ)
Q:配置了但 $upstream_cache_status 一直是 BYPASS?
A:检查:响应里是否带 Set-Cookie(默认不缓存);上游是否返回 Cache-Control: no-cache/private;proxy_cache_bypass 条件是否命中。
Q:POST 请求会被缓存吗?
A:默认只缓存 GET/HEAD。POST 需显式加进 proxy_cache_methods,但除非明确知道后果,不建议。
Q:缓存目录权限怎么设?
A:属主设为 Nginx worker 运行用户(通常 www-data 或 nginx),proxy_cache_path 指定即可,Nginx 会自动建目录结构。