在 Linux 环境下,Nginx 的缓存功能主要涉及两个层面:反向代理缓存(Proxy Cache) 和 静态文件缓存(FastCGI/Static Cache),最常用的是 反向代理缓存,它可以将后端服务器(如 Apache、Tomcat、Node.js 等)返回的内容缓存到本地磁盘或内存中,从而减轻后端压力并提升访问速度。
以下是关于 Nginx 缓存的详细配置指南、关键指令说明及最佳实践。
核心配置示例
在 nginx.conf 或对应的 server/location 块中添加以下配置:
http {
# 1. 定义缓存区域
# proxy_cache_path: 缓存路径
# levels: 缓存目录层级结构 (1:2 表示两级目录,帮助分散文件数量)
# keys_zone: 内存中存储缓存键和元数据的区域大小
# max_size: 磁盘上缓存的最大容量
# inactive: 非活动多久后删除缓存 (默认 10 分钟)
# use_temp_path: 是否使用临时路径 (建议设为 off,避免跨文件系统移动文件的开销)
proxy_cache_path /var/cache/nginx/proxy levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
server {
listen 80;
server_name example.com;
location / {
# 2. 启用缓存
proxy_cache my_cache;
# 3. 定义哪些状态码可以缓存 (默认只缓存 200, 301, 302)
proxy_cache_valid 200 302 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid any 1m;
# 4. 设置缓存键 (默认使用 $scheme + $proxy_host + $request_uri)
# URL 中有查询参数且不影响内容,可忽略
proxy_cache_key "$scheme$request_method$host$request_uri";
# 5. 设置后端服务器
proxy_pass http://backend_servers;
# 6. 处理缓存未命中或过期的行为
# add_header X-Cache-Status $upstream_cache_status; # 调试用,显示 HIT/MISS/BYPASS/EXPIRED
}
}
}
关键指令详解
proxy_cache_path
- 路径:必须存在且 Nginx 进程用户(通常是
nginx或www-data)有写权限。 - keys_zone:内存区域,用于存储缓存键和元数据。1MB 内存可存储约 8000 个键。
- max_size:磁盘缓存上限,当超出时,Nginx 会删除最少使用的文件。
- inactive:非活动超时时间,如果缓存文件在此时间内未被访问,将被删除,注意:这与
proxy_cache_valid不同,inactive是基于访问时间,而valid是基于生成时间。
proxy_cache_valid
- 定义不同 HTTP 状态码的缓存有效期。
- 示例:
proxy_cache_valid 200 302 10m;表示 200 和 302 状态码的内容缓存 10 分钟。 any表示其他所有状态码。
proxy_cache_key
- 决定缓存的唯一标识。
- 常见变量:
$scheme:http 或 https$host:主机名$request_uri:完整 URI(包括查询参数)$cookie_sessionid:如果用户登录状态影响内容,可加入 cookie 键。
- 注意:URL 查询参数不影响内容(如
?sort=asc和?sort=desc返回相同内容),应清理 URI 或使用自定义逻辑。
proxy_cache_bypass 和 proxy_no_cache
proxy_cache_bypass:如果表达式为真,则不从缓存获取,而是直接向后端请求,但不存储新结果到缓存。proxy_cache_bypass $http_cache_control;
proxy_no_cache:如果表达式为真,则不存储结果到缓存,但仍向后端请求。
proxy_no_cache $http_pragma $http_authorization;
add_header X-Cache-Status
- 用于调试,返回缓存状态:
HIT:缓存命中MISS:缓存未命中,从后端获取BYPASS:绕过缓存EXPIRED:缓存已过期,从后端刷新
高级技巧与最佳实践
清除特定缓存
Nginx 本身没有内置的“删除单个文件”命令,但可以通过以下方式实现:
- 方案 A:重命名文件(推荐)
mv /var/cache/nginx/proxy/1/23/456789012345678901234567890123 /var/cache/nginx/proxy/1/23/456789012345678901234567890123.bak
Nginx 会自动删除
.bak文件(如果配置了use_temp_path=off则不会自动删除,需手动清理)。 - 方案 B:使用第三方模块
如nginx-cache-purge模块,可通过 URL 清除缓存:location /purge/ { allow 127.0.0.1; deny all; proxy_cache_purge my_cache "$scheme$request_method$host$request_uri"; } - 方案 C:应用层清除
在后端代码中,当内容更新时,通过 HTTP 头或 API 通知 Nginx 清除缓存(需配合proxy_cache_purge或脚本)。
缓存动态内容
- 对于 API 或动态页面,确保
proxy_cache_key包含足够的标识(如用户 ID、Cookie),避免不同用户看到相同内容。 - 使用
proxy_cache_min_uses:只有当某个 URI 被请求超过 N 次后才缓存,避免频繁访问的页面被缓存。proxy_cache_min_uses 5;
处理浏览器缓存
Nginx 缓存是服务器端缓存,还需配合浏览器缓存:
location ~ .(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
监控缓存命中率
- 查看日志中的
X-Cache-Status头。 - 使用
nginx_status模块监控缓存大小和命中率。 - 定期检查
/var/cache/nginx/目录大小,确保未超出max_size。
缓存压缩
- 启用
gzip可减少传输数据量,但会增加 CPU 开销。 - 缓存压缩后的内容需设置
proxy_cache_key包含$gzip变量,否则未启用 gzip 的请求会获取到压缩内容导致乱码。proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args$gzip";
常见问题排查
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 缓存未生效 | proxy_cache_key 包含动态参数(如时间戳) |
清理 URI 或使用 proxy_cache_bypass |
| 缓存不更新 | proxy_cache_valid 时间过长 |
缩短 valid 时间或使用 proxy_cache_purge |
| 缓存目录权限错误 | Nginx 用户无写权限 | 修改 /var/cache/nginx 所有权:chown -R nginx:nginx /var/cache/nginx |
| 缓存文件过大 | max_size 设置过大或 inactive 过短 |
调整 max_size 和 inactive 参数 |
| 后端返回 502/504 | 缓存路径磁盘满 | 清理缓存或增加 max_size |
Nginx 缓存是提升 Web 性能的关键手段,合理配置 proxy_cache_path、proxy_cache_valid 和 proxy_cache_key 可以显著降低后端负载,对于动态内容,需谨慎处理缓存键和清除策略,建议在生产环境中启用 X-Cache-Status 头进行监控,并根据实际流量调整缓存参数。
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/477928.html



