利用 Nginx 进行服务器端缓存(反向代理缓存)配置,可以有效减少后端服务器压力,提升静态资源或动态内容的响应速度。以下是详细的配置步骤和最佳实践:

一、Nginx 缓存模块简介

Nginx 主要通过以下两个模块实现缓存:

 

  1. ngx_http_proxy_module:反向代理功能,用于转发请求到后端服务器。
  2. ngx_http_cache_module:缓存模块,用于存储后端响应结果。

 

核心原理:Nginx 作为反向代理,第一次请求后端服务器时,将响应内容缓存到本地磁盘 / 内存;后续相同请求直接返回缓存内容,无需再次访问后端。

二、配置步骤

1. 准备工作

  • 检查模块支持
    确认 Nginx 已编译包含 proxy 和 cache 模块。执行以下命令:
    bash
    nginx -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 模块(需编译时添加)
    1. 重新编译 Nginx 并启用模块:
      bash
      ./configure --add-module=/path/to/ngx_http_cache_purge
      make && make install
      
    2. 配置清理接口:
      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 即可删除对应缓存。

  • 方法二:手动删除缓存文件
    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 中的日志格式:
    nginx
    log_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 分钟)。
  • 避免缓存敏感数据
    对包含用户认证信息(如 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 实现故障转移:
    nginx
    proxy_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;
  }
}

六、常见问题排查

  1. 缓存未生效(始终返回 MISS)
    • 检查 proxy_cache 是否启用(是否关联到正确的 keys_zone)。
    • 确认 proxy_cache_key 是否包含必要变量(如 $host 避免跨域名缓存污染)。
    • 查看响应头是否有 Cache-Control: no-cache(可能被后端或 Nginx 配置覆盖)。
  2. 缓存数据不一致
    • 确保后端数据更新时,通过接口清理对应缓存(如调用 /purge 接口)。
    • 检查 inactive 时间是否过长,导致旧数据未被及时删除。
  3. 磁盘空间不足
    • 调整 max_size 或 inactive 时间,释放过期缓存。
    • 启用 proxy_cache_use_stale error timeout,在后端故障时继续返回旧缓存。

 

通过以上配置,Nginx 可高效实现服务器端缓存,显著提升网站性能和后端负载能力。实际应用中需结合业务场景动态调整缓存策略,并定期监控缓存命中率和资源占用。