# 如何利用Nginx进行服务器端缓存配置？

> 来源：梦飞idc云平台 | 原文：https://www.mfisp.com/36341.html | 发布：2025-05-15 | 更新：2025-05-15 | 分类：投稿分享

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

 

### **一、Nginx 缓存模块简介**

 

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

  
 
1. **`ngx_http_proxy_module`**：反向代理功能，用于转发请求到后端服务器。 
1. **`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
``` 
  1. 配置清理接口： 

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 配置覆盖）。 
1. **缓存数据不一致**

 
 
  - 确保后端数据更新时，通过接口清理对应缓存（如调用 `/purge` 接口）。 
  - 检查 `inactive` 时间是否过长，导致旧数据未被及时删除。 
1. **磁盘空间不足**

 
 
  - 调整 `max_size` 或 `inactive` 时间，释放过期缓存。 
  - 启用 `proxy_cache_use_stale error timeout`，在后端故障时继续返回旧缓存。 

  

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

---
本页由 梦飞idc云平台（https://www.mfisp.com）提供。站点导航见 https://www.mfisp.com/llms.txt
