0%

Nginx缓存

Nginx 缓存配置详解:代理缓存与静态资源缓存策略

缓存是提升 Web 服务性能的关键技术,Nginx 作为高性能代理服务器,通过代理缓存(Proxy Cache)和客户端缓存(Expires)减少后端服务器压力,加速资源响应。本文详细讲解 Nginx 缓存的工作原理、核心配置及实战案例,帮助构建高效的缓存体系。

缓存的三种类型与 Nginx 定位

在 Web 架构中,缓存按存储位置可分为三类:

缓存类型 存储位置 作用
服务端缓存 后端服务器(如 Redis、Memcached) 缓存数据库查询结果、业务数据等
代理缓存 代理服务器(如 Nginx) 缓存后端返回的静态资源或 API 响应,减少后端重复处理
客户端缓存 浏览器本地 缓存静态资源(如图片、CSS),减少网络请求

Nginx 的角色:主要实现代理缓存,同时通过expires指令控制客户端缓存策略,是连接后端服务与客户端的 “中间缓存层”。

Nginx 代理缓存(Proxy Cache):减少后端请求

Nginx 代理缓存将后端服务器的响应数据存储在本地磁盘或内存中,当后续有相同请求时,直接返回缓存内容,无需转发至后端。

核心配置指令

代理缓存的配置需两步:先在http块定义缓存存储路径和参数(proxy_cache_path),再在location块启用缓存(proxy_cache)。

指令 作用 适用块
proxy_cache_path 定义缓存存储路径、内存区域、有效期等 http
proxy_cache 启用缓存,指定关联的内存区域 http/server/location
proxy_cache_key 定义缓存的唯一标识(key) 同上
proxy_cache_valid 对不同状态码设置缓存有效期 同上
proxy_cache_min_uses 最少请求次数达到后才缓存 同上

基础配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
http {
# 1. 定义缓存存储参数(http块内)
proxy_cache_path /var/nginx/cache # 缓存文件存储路径
levels=1:2 # 目录层级(1级子目录+2级子目录,避免单目录文件过多)
keys_zone=my_cache:10m # 内存区域名称my_cache,大小10M(存储缓存key和元数据)
max_size=10g # 缓存最大磁盘占用10G,超出则删除最少访问的缓存
inactive=7d # 7天内未被访问的缓存自动清理
use_temp_path=off; # 禁用临时文件目录(直接写入缓存路径,减少IO)

server {
listen 80;
server_name example.com;

# 2. 在location块启用缓存
location /api {
proxy_pass http://backend; # 转发到后端服务

# 启用缓存,关联my_cache区域
proxy_cache my_cache;

# 定义缓存key(由主机名、URI、参数组成,确保唯一)
proxy_cache_key $host$uri$is_args$args;

# 对状态码200/304的响应缓存12小时,其他状态码缓存10分钟
proxy_cache_valid 200 304 12h;
proxy_cache_valid any 10m;

# 最少被请求2次后才缓存(避免缓存一次性请求)
proxy_cache_min_uses 2;

# 向响应头添加缓存状态(HIT=命中,MISS=未命中,便于调试)
add_header X-Cache-Status $upstream_cache_status;
}
}
}

缓存命中逻辑与状态码

  • 缓存命中(HIT):请求的key在缓存中存在,且未过期,直接返回缓存内容;
  • 缓存未命中(MISS)key不存在或已过期,转发请求到后端,并存入缓存;
  • 不缓存(BYPass):因配置规则(如proxy_no_cache)跳过缓存。

通过X-Cache-Status响应头可查看缓存状态,便于调试。

缓存排除:无需缓存的场景

部分请求(如登录、购物车等动态内容)不应缓存,可通过proxy_no_cache排除:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
location / {
proxy_cache my_cache;
proxy_cache_key $host$uri$is_args$args;

# 满足以下任一条件则不缓存:
# 1. 请求路径包含/login或/register
# 2. 请求参数带nocache=1
# 3. 请求头有Pragma: no-cache(浏览器禁用缓存时发送)
set $nocache 0;
if ($request_uri ~ ^/(login|register)) {
set $nocache 1;
}
proxy_no_cache $nocache $arg_nocache $http_pragma;
}

客户端缓存控制:expires指令

expires指令通过设置响应头的ExpiresCache-Control,告诉浏览器缓存静态资源(如图片、CSS),减少重复请求。

基础配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
# 对图片、CSS、JS设置不同的缓存时间
location ~* \.(jpg|jpeg|png|gif)$ {
root /var/www/static;
expires 7d; # 缓存7天
add_header Cache-Control "public, max-age=604800"; # 与expires同步(7*24*3600=604800秒)
}

location ~* \.(css|js)$ {
root /var/www/static;
expires 1d; # 缓存1天
add_header Cache-Control "public, max-age=86400";
}
}

客户端缓存与 304 状态码

当浏览器缓存的资源过期时,会发送请求验证资源是否更新,验证方式有两种:

  • Last-Modified:浏览器发送If-Modified-Since头,后端检查资源最后修改时间,未修改则返回304 Not Modified
  • ETag:浏览器发送If-None-Match头,后端比对资源唯一标识(如哈希值),未修改则返回 304。

Nginx 会自动处理这两种验证,无需额外配置,304 响应不返回实体内容,仅告知浏览器使用本地缓存。

静态资源缓存实战配置

针对静态资源(如图片、JS、CSS),结合代理缓存和客户端缓存,实现 “双层缓存”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
http {
# 定义静态资源缓存路径
proxy_cache_path /var/nginx/static_cache
levels=1:2
keys_zone=static_cache:50m
max_size=50g
inactive=30d;

server {
listen 80;
server_name static.example.com;

# 静态资源缓存配置
location / {
root /var/www/static;

# 代理缓存(本地存储,减少后端请求)
proxy_cache static_cache;
proxy_cache_key $uri$is_args$args; # 以URI和参数为key
proxy_cache_valid 200 30d; # 成功响应缓存30天

# 客户端缓存(浏览器存储,减少网络请求)
expires 7d;
add_header Cache-Control "public, max-age=604800";

# 不缓存404响应
proxy_cache_valid 404 0;
}
}
}

缓存优化与注意事项

  1. 缓存 key 设计
    • 动态内容:$host$uri$is_args$args(包含参数,确保不同参数请求不冲突);
    • 静态资源:$uri(忽略参数,如/img/logo.png?version=1?version=2应视为不同资源,需包含参数)。
  2. 缓存清理
    • 手动删除缓存文件:rm -rf /var/nginx/cache/*(需重启 Nginx 或发送reload信号);
    • 使用第三方模块(如ngx_cache_purge)实现 URL 级别的缓存清理。
  3. 避免缓存动态内容
    • POST请求默认不缓存(可通过proxy_cache_methods修改,但不推荐);
    • 带用户认证的请求(如Authorization头)应排除缓存。
  4. 内存与磁盘平衡
    • keys_zone大小需足够存储缓存 key(1M 约存 8000 个 key);
    • max_size不应超过磁盘可用空间,避免缓存写入失败。

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10

域名更新通知

您好!我们的官方域名已更新为 zhhll.com.cn。 请收藏新域名以获取最佳访问体验。