Nginx 缓存工作原理

当 Nginx 作为代理缓存时,它可以将后端服务器响应的内容存储在本地磁盘上。后续请求如果命中缓存,Nginx 将直接从磁盘读取内容返回,而无需再次向后端服务发送请求。

基础配置示例

Nginx 代理缓存主要分为服务端代理缓存和浏览器缓存两大类。

1. 服务端代理缓存 (Proxy Cache)缓存配置:将后端服务器返回的内容缓存到 Nginx 本地磁盘。主要分为两个部分:在 http 块定义缓存空间,在 server/location 块启用缓存。

http {
    # 1. 定义缓存路径及参数
    # levels:目录层级; keys_zone:缓存名与内存占用; inactive:有效期; max_size:磁盘占用上限
    proxy_cache_path /data/nginx/cache 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. 设置缓存有效期
            proxy_cache_valid 200 302 10m;
            proxy_cache_valid 404      1m;

            # 4. 转发请求
            proxy_pass http://backend_upstream;

            # 5. 在响应头中显示缓存状态(便于调试)
            add_header X-Cache-Status $upstream_cache_status;
        }
    }
}

2. 浏览器缓存 (Browser Cache)配置:通过 HTTP 响应头告知浏览器存在缓存的静态资源,减少网络请求次数。

server {
    listen 80;
    server_name example.com;

    location / {
        root /usr/share/nginx/html;
        index index.html;
    }

    # 静态资源处理:开启协商缓存 (ETag/Last-Modified),Nginx 默认开启 ETag 和 Last-Modified
    # ETag: 开启后,浏览器再次请求时会携带 If-None-Match 验证资源是否变动。Last-Modified: 配合 If-Modified-Since 使用
    etag on;                # 默认开启
    if_modified_since exact; # 默认开启,基于修改时间校验

    # 设置 Cache-Control 强缓存 1 小时
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 1h;
        add_header Cache-Control "public, must-revalidate";
    }
}

proxy_cache_path 常用指令详解

Nginx 代理缓存配置的关键的指令参数直接决定了缓存的存储结构和清理效率。

参数名 意义 可选/推荐值
proxy_cache_path 缓存文件在磁盘上的存储根目录。 需确保 Nginx 用户有写权限。
levels 目录层级结构。1:2 表示两级子目录。 推荐 1:2,避免单目录下文件过多。
keys_zone 定义共享内存空间的名称和大小(存索引)。 name:10m (10MB 可存约 8 万个 key)。
max_size 磁盘缓存占用的最大空间上限。 例如 10g。超出后按 LRU 算法清理。
inactive 存留期。在此时间内未被访问的文件将被删除。 默认 10m,推荐 60m 或更长。
use_temp_path 是否使用临时路径。 推荐 off,直接写入缓存目录提高效率。

高级优化配置

1. 缓存键定义 (proxy_cache_key)

默认使用 URL 作为键。如果您的业务涉及多域名或移动端适配,可能需要修改:

# 包含协议、主机名、请求路径及参数
proxy_cache_key "$scheme$proxy_host$request_uri";

2. 缓存合并 (proxy_cache_lock)

当多个客户端同时请求一个未缓存的资源时,只允许一个请求发往后端,其余请求等待第一个完成后直接读取缓存。

proxy_cache_lock on;
proxy_cache_lock_timeout 5s;

3. 绕过缓存 (proxy_cache_bypass)

在某些情况下(如管理员登录后),需要看到实时数据而非缓存:

# 如果请求头包含 nocache,则不使用缓存
proxy_cache_bypass $http_nocache;
安全与性能建议: Nginx 代理缓存可以极大减少握手后的解密及后端处理压力。 请务必定期检查磁盘剩余空间,防止 max_size 设置过大导致磁盘撑爆。

调试缓存状态

通过配置 add_header X-Cache-Status $upstream_cache_status;,您可以在浏览器 F12 响应头中看到以下状态:

  • HIT: 命中缓存,直接从磁盘读取。
  • MISS: 未命中,请求已转发到后端,并正在生成缓存。
  • EXPIRED: 缓存已过期,请求转发到后端获取新内容。
  • BYPASS: 根据配置绕过了缓存,直接访问后端。

验证与生效

# 检查配置文件语法
sudo nginx -t

# 重新加载配置
sudo nginx -s reload
#或 sudo systemctl reload nginx