利用 Nginx 进行服务器端缓存(反向代理缓存)配置,可以有效减少后端服务器压力,提升静态资源或动态内容的响应速度。以下是详细的配置步骤和最佳实践:
一、Nginx 缓存模块简介
Nginx 主要通过以下两个模块实现缓存:
ngx_http_proxy_module
:反向代理功能,用于转发请求到后端服务器。ngx_http_cache_module
:缓存模块,用于存储后端响应结果。
核心原理:Nginx 作为反向代理,第一次请求后端服务器时,将响应内容缓存到本地磁盘 / 内存;后续相同请求直接返回缓存内容,无需再次访问后端。
二、配置步骤
1. 准备工作
-
检查模块支持:
确认 Nginx 已编译包含proxy
和cache
模块。执行以下命令:bashnginx -V 2>&1 | grep -E "proxy|cache"
输出中应包含--with-http_proxy_module
和--with-http_cache_module
。- 若未包含,需重新编译 Nginx(参考 Nginx 官方文档)。
-
创建缓存目录:bash
sudo mkdir -p /var/cache/nginx/cache # 路径可自定义 sudo chown -R nginx:nginx /var/cache/nginx # 设置权限(用户需与 Nginx 运行用户一致)
2. 全局缓存配置(http 块)
在 Nginx 配置文件(通常为
/etc/nginx/nginx.conf
)的 http
块中,定义缓存区域和策略:
nginx
http {
# 定义缓存区域(levels、keys_zone、max_size 为必填项)
proxy_cache_path /var/cache/nginx/cache # 缓存存储路径
levels=1:2 # 缓存目录层级(1:2 表示两层目录,如 /a/b/cache_key)
keys_zone=my_cache:10m # 缓存键共享内存区(名称:大小,10m 表示占用 10MB 内存)
max_size=10g # 缓存最大磁盘占用(超过后按策略淘汰)
inactive=60m # 缓存项在指定时间内未被访问则删除(60分钟)
use_temp_path=on; # 是否使用临时路径缓存(默认 on,建议保留)
# 其他全局配置(如 MIME 类型、日志等)...
}
关键参数说明:
参数 | 说明 |
---|---|
levels |
缓存目录层级,用于分散文件存储,避免单目录文件过多(建议 1:2 或 2:2)。 |
keys_zone |
缓存键的元数据存储区,内存大小需根据缓存键数量调整(1MB 约存储 8000 个键)。 |
max_size |
缓存总大小,超过后按 proxy_cache_use_stale 策略淘汰旧缓存。 |
inactive |
缓存项未被访问的超时时间,超时后自动删除(仅在内存中标记,磁盘空间延迟释放)。 |
use_temp_path |
是否使用临时目录缓存数据(建议开启,避免缓存写入过程中返回不完整数据)。 |
3. 反向代理缓存配置(server/location 块)
在具体的
server
或 location
块中,启用缓存并关联到后端服务器:
nginx
server {
listen 80;
server_name example.com;
location / {
# 反向代理到后端服务器(如 Node.js、PHP-FPM 等)
proxy_pass http://backend_server; # 后端地址,如 http://127.0.0.1:8080
# 启用缓存并关联全局缓存区域
proxy_cache my_cache; # 使用 http 块中定义的 keys_zone 名称(my_cache)
proxy_cache_key $scheme$host$request_uri; # 缓存键规则(基于协议、域名、URI)
# 缓存有效期配置(按响应状态码设置不同缓存时间)
proxy_cache_valid 200 302 12h; # 成功响应(200/302)缓存 12 小时
proxy_cache_valid 404 1m; # 404 错误缓存 1 分钟
proxy_cache_valid any 5m; # 其他状态码默认缓存 5 分钟(可选)
# 缓存更新策略
proxy_cache_use_stale updating; # 缓存过期时,返回旧缓存并后台更新
proxy_cache_background_update on; # 后台异步更新缓存(需 Nginx 1.13.9+)
# 忽略后端返回的 Cache-Control 头,强制使用 Nginx 配置
proxy_ignore_headers Cache-Control;
# 传递必要的请求头(如 Cookie,按需开启)
proxy_pass_request_cookie on;
}
}
关键参数说明:
proxy_cache_key
:定义缓存键的生成规则,需确保相同请求生成唯一键。常见变量:$scheme
:协议(http/https)。$host
:域名(避免不同域名共享缓存)。$request_uri
:完整 URI(包含查询参数,如?id=123
)。- 若需排除查询参数,可改为
$uri
(仅路径部分)。
proxy_cache_valid
:按状态码设置不同缓存时间,any
表示所有状态码。proxy_cache_use_stale
:缓存过期时的处理策略,updating
表示使用旧缓存并触发更新。
4. 高级配置:缓存分层与控制
-
按请求头缓存(如区分用户登录状态):nginx
location / { # 仅缓存未登录用户的请求(通过 Cookie 判断) if ($http_cookie !~* "logged_in=1") { proxy_cache my_cache; } }
-
禁止缓存特定请求(如带授权头):nginx
location / { if ($http_authorization) { proxy_no_cache 1; # 禁止缓存带 Authorization 头的请求 add_header Cache-Control "no-cache, no-store"; } }
-
缓存分层(内存 + 磁盘):nginx
proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m loader_files=1000 # 启动时一次性加载的缓存元数据文件数 loader_sleep=200ms # 加载间隔 loader_threshold=300m; # 加载阈值(超过则分批次加载)
三、缓存管理与监控
1. 查看缓存状态
在
location
块中添加 proxy_cache_status
变量,返回缓存状态:
nginx
location / {
# 其他配置...
add_header X-Cache $proxy_cache_status; # 响应头中添加缓存状态
}
状态值说明:
HIT
:缓存命中,直接返回缓存内容。MISS
:缓存未命中,请求后端服务器并缓存结果。EXPIRED
:缓存过期,请求后端服务器并更新缓存。STALE
:使用旧缓存(proxy_cache_use_stale
生效时)。
示例响应头:
http
X-Cache: HIT
2. 清理缓存
Nginx 本身不提供内置缓存清理接口,需借助第三方模块或脚本:
-
方法一:使用
ngx_http_cache_purge
模块(需编译时添加):- 重新编译 Nginx 并启用模块:
bash
./configure --add-module=/path/to/ngx_http_cache_purge make && make install
- 配置清理接口:
nginx
location /purge { allow 127.0.0.1; # 允许清理的 IP deny all; proxy_cache_purge my_cache $scheme$host$request_uri; # 按缓存键清理 }
发送POST
请求到/purge?uri=/path/to/clear
即可删除对应缓存。
- 重新编译 Nginx 并启用模块:
-
方法二:手动删除缓存文件:bash
# 按缓存键哈希值删除(需先计算键的哈希值) key_hash=$(echo -n "$scheme$host$request_uri" | md5sum | cut -c1-2)/$(echo -n "$scheme$host$request_uri" | md5sum | cut -c3-4)/$(echo -n "$scheme$host$request_uri" | md5sum) rm -f /var/cache/nginx/cache/$key_hash
3. 监控缓存命中率
通过 Nginx 日志或外部工具监控缓存命中情况:
-
在日志中记录缓存状态:
修改nginx.conf
中的日志格式:nginxlog_format cache_log '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$proxy_cache_status"'; access_log /var/log/nginx/access.log cache_log;
日志中会显示每行请求的$proxy_cache_status
值,通过统计HIT
与MISS
的比例计算命中率。 -
使用第三方工具:
- Prometheus + Nginx Exporter:监控 Nginx 指标(如缓存命中数)。
- Grafana:可视化缓存命中率趋势。
四、最佳实践与注意事项
1. 缓存策略优化
-
区分动态与静态内容:
- 静态资源(如图片、CSS)优先通过浏览器缓存(
Cache-Control: max-age=31536000
)处理,减少 Nginx 缓存压力。 - 动态内容(如 API 接口)使用 Nginx 反向代理缓存,设置合理过期时间(如 5-30 分钟)。
- 静态资源(如图片、CSS)优先通过浏览器缓存(
-
避免缓存敏感数据:
对包含用户认证信息(如 Cookie、Authorization 头)的请求,禁用缓存(proxy_no_cache 1
)。 -
热点数据预热:
通过脚本提前请求热点 URL,将数据载入缓存(如启动时执行curl -I http://example.com/hot-path
)。
2. 性能调优
-
调整内存与磁盘占用:
keys_zone
大小:根据预估的缓存键数量调整(1MB ≈ 8000 键),避免频繁内存回收。max_size
:根据服务器磁盘空间设置,建议为后端数据总量的 1-3 倍。
-
启用 Sendfile 加速:nginx
http { sendfile on; tcp_nopush on; }
减少内核空间与用户空间的数据拷贝,提升静态文件传输效率。
3. 高可用性架构
- 缓存服务器集群:
将 Nginx 缓存节点独立部署为集群,避免单机缓存失效影响全局。 - 后端服务器健康检查:
结合proxy_next_upstream
实现故障转移:nginxproxy_next_upstream error timeout invalid_header http_500;
五、示例配置文件
nginx
# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
http {
include mime.types;
default_type application/octet-stream;
# 全局缓存配置
proxy_cache_path /var/cache/nginx/cache
levels=1:2
keys_zone=my_cache:20m
max_size=20g
inactive=30m
use_temp_path=on;
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend; # 后端服务器组(需在 http 块中定义 upstream)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 缓存配置
proxy_cache my_cache;
proxy_cache_key $scheme$host$uri$is_args$args; # 包含查询参数
proxy_cache_valid 200 302 6h;
proxy_cache_valid 404 10m;
add_header X-Cache $proxy_cache_status;
# 禁止缓存带 Cookie 的请求
if ($http_cookie ~* "sessionid") {
proxy_no_cache 1;
add_header Cache-Control "no-cache";
}
}
}
# 后端服务器组
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
}
六、常见问题排查
-
缓存未生效(始终返回 MISS)
- 检查
proxy_cache
是否启用(是否关联到正确的keys_zone
)。 - 确认
proxy_cache_key
是否包含必要变量(如$host
避免跨域名缓存污染)。 - 查看响应头是否有
Cache-Control: no-cache
(可能被后端或 Nginx 配置覆盖)。
- 检查
-
缓存数据不一致
- 确保后端数据更新时,通过接口清理对应缓存(如调用
/purge
接口)。 - 检查
inactive
时间是否过长,导致旧数据未被及时删除。
- 确保后端数据更新时,通过接口清理对应缓存(如调用
-
磁盘空间不足
- 调整
max_size
或inactive
时间,释放过期缓存。 - 启用
proxy_cache_use_stale error timeout
,在后端故障时继续返回旧缓存。
- 调整
通过以上配置,Nginx 可高效实现服务器端缓存,显著提升网站性能和后端负载能力。实际应用中需结合业务场景动态调整缓存策略,并定期监控缓存命中率和资源占用。