Nginx 缓存配置:原理、应用与实战指南

Nginx 作为一款高性能的 Web 服务器和反向代理服务器,其缓存功能能够有效提升网站性能、降低后端服务器压力。在GIS领域,特别针对地图加载时的大量请求,缓存的配置必不可少。

1. 理解Nginx缓存

缓存(Cache)的本质是一种临时存储机制,它将频繁访问的数据存储在靠近请求端的位置,以便在后续请求到来时,能够快速获取数据,而无需再次经过复杂的处理流程或访问后端服务器。
在 Nginx 中,缓存功能主要用于存储后端服务器响应的内容,无论是静态资源(如图片、CSS、JS 文件),还是动态 API 返回的数据,都可以通过缓存进行复用。

1.1. Nginx 缓存的工作流程

Nginx 缓存的工作流程可以简单概括为 “缓存写入” 和 “缓存读取” 两个阶段:

  • 缓存写入:当 Nginx 接收到客户端请求时,它会先检查请求是否命中缓存。如果未命中,Nginx 会将请求转发给后端服务器,获取响应内容。在接收到响应后,Nginx 会根据配置规则将响应内容存储到缓存中,并记录缓存键与内容的对应关系。
  • 缓存读取:当后续请求到达时,Nginx 会根据请求的特征生成缓存键,并在缓存中查找对应的内容。如果找到匹配的缓存键,Nginx 将直接从缓存中读取数据并返回给客户端,完成请求处理;如果未找到,则重复 “缓存写入” 的流程。

1.2. Nginx 缓存的作用

Nginx 缓存的核心作用体现在以下几个方面:

  • 加速响应速度:直接从缓存中读取数据,避免了与后端服务器的交互,极大缩短了响应时间,提升用户体验;
  • 降低后端压力:大量重复请求由缓存直接处理,减少了后端服务器的负载,节省计算资源和带宽成本;
  • 提高系统可用性:当后端服务器出现故障或维护时,Nginx 可以继续提供缓存中的数据,保证服务的连续性,避免前端出现错误页面;

2. 基础缓存配置

该章节通过简单配置实现缓存的初步使用。

2.1 创建缓存路径

首先,需要在 Nginx 配置文件中定义缓存路径和缓存区域。以下是一个基础的缓存配置示例:

1
2
# 在 http 块中添加
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;

参数说明

  • /var/cache/nginx:缓存文件存储路径(需提前创建并确保 Nginx 有读写权限);
  • levels=1:2:缓存目录结构(一级目录 1 个字符,二级目录 2 个字符,如 c/ab/key);
  • keys_zone=my_cache:10m:其中,my_cache为自定义的缓存名称,并分配10m的缓存空间;
  • max_size=10g:磁盘缓存的最大空间(超过时按 LRU 淘汰)。
  • inactive=60m:缓存数据在未被访问时的保留时间,即如果60分钟内没有请求访问缓存的内容,则会被自动清除(7d,保留时间为7天)。
  • use_temp_path=off:直接在缓存目录写文件,避免临时路径的额外 I/O。

2.2. 启用缓存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 80;
server_name your_domain.com;

location / {
proxy_pass http://backend_server; # 后端服务器地址

# 启用缓存
proxy_cache my_cache;
proxy_cache_key "$scheme$host$request_uri";
proxy_cache_valid 200 304 12h; # 对200和304状态码的响应缓存12小时
proxy_cache_valid any 5m; # 其他状态码缓存5分钟
}
}

配置说明

  • proxy_cache:指定使用的缓存区域,区域名称是由上一步中keys_zone创建的;
  • proxy_cache_key:定义了缓存键的生成规则,根据请求的协议、主机名和 URI 生成唯一的缓存键;
  • proxy_cache_valid:设置了不同 HTTP 状态码的缓存时间;

通过以上配置,就可以使用Nginx缓存啦。

3. 缓存配置指令

本章节参考官网的说明格式,对常用配置项进行整理,官网文档:https://nginx.org/en/docs/http/ngx_http_proxy_module.html

3.1. proxy_cache

1
2
3
语法:proxy_cache zone | off;
默认:proxy_cache off;
位置:http, server, location

定义用于缓存的共享内存区域。 同一区域可以在多个地方使用。

3.2. proxy_cache_path

1
2
3
语法:proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [min_free=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
默认:proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [min_free=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
位置:http

设置缓存的路径和其他参数。
缓存数据存储在文件中,缓存中的文件名是MD5函数将proxy_cache_key的值加密得到的。
该参数定义了缓存的层次结构: 从 1 到 3,每个级别接受值 1 或 2。 例如:

1
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m;

缓存中的文件名将如下所示:

1
/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c

其他参数前往官网查看。

3.3. proxy_cache_use_stale

1
2
3
语法:proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | off ...;
默认:proxy_cache_use_stale off;
位置:http, server, location

确定在哪些情况下可以使用过时的缓存响应。

3.4. proxy_cache_background_update

1
2
3
4
语法:	proxy_cache_background_update on | off;
默认: proxy_cache_background_update off;
位置: http, server, location
该命令出现于version 1.11.10.

当过期的缓存返回给客户端时,允许启动后台子请求更新过期的缓存项。请注意,在更新时必须允许使用过时的缓存响应。

3.5. proxy_cache_bypass

1
2
3
语法:	proxy_cache_bypass string ...;
默认: —
位置: http, server, location

定义不从缓存中获取响应的条件。 如果字符串参数的至少一个值不为空且不等于 “0”,则不会从缓存中获取响应:

1
2
proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
proxy_cache_bypass $http_pragma $http_authorization;

可以与 proxy_no_cache 指令一起使用。

3.6. proxy_ignore_headers

1
2
3
语法:	proxy_ignore_headers field ...;
默认: —
Context: http, server, location

禁用来自代理服务器的某些响应标头字段的处理。 可以忽略以下字段:X-Accel-Redirect”, “X-Accel-Expires”, “X-Accel-Limit-Rate” (1.1.6), “X-Accel-Buffering” (1.1.6), “X-Accel-Charset” (1.1.6), “Expires”, “Cache-Control”, “Set-Cookie” (0.8.44), and “Vary” (1.7.7)。
如果未禁用,则这些标头字段的处理将如下所示影响:

  • “X-Accel-Expires”, “Expires”, “Cache-Control”, “Set-Cookie”, and “Vary” 设置响应缓存的参数;
  • “X-Accel-Redirect” :执行内部 重定向到指定的 URI;
  • “X-Accel-Limit-Rate” :设置速率 限制向客户传输响应;
  • “X-Accel-Buffering” :启用或禁用响应的缓冲;
  • “X-Accel-Charset”: 设置响应的所需字符集。

4. 缓存测试

当前在配置文件中新增了一个关于高德地图相关的链接。

1
2
3
4
5
6
7
8
9
10
11
location /webapi.amap.com/ {
proxy_set_header Accept-Encoding "";
proxy_pass http://webapi.amap.com/;
# 缓存设置
proxy_cache amap_cache;
proxy_cache_key "$scheme$host$request_uri$args";
proxy_cache_valid 200 304 10s;
proxy_cache_valid any 10m;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_cache_background_update on;
}

4.1. 缓存状态

新增以下配置:

1
add_header Nginx-Cache $upstream_cache_status;

$upstream_cache_status包含以下几种状态:

  • MISS:未命中,请求被传送到后端;
  • HIT:缓存命中;
  • EXPIRED: 缓存已经过期请求被传送到后端;
  • UPDATING:正在更新缓存,将使用旧的应答;
  • STALE:后端将得到过期的应答;

增加该配置后,可以在请求后查看响应头里面多了一个参数nginx-cache ,这样就可以根据这个值判断是否使用了缓存。

4.2. Cache-Control的影响

多次请求中 Nginx 缓存状态始终为 “MISS”,经排查发现源站响应头包含Cache-Control: max-age=0。该 HTTP 缓存控制字段会强制客户端(浏览器 / 代理)跳过缓存直接回源请求。
为了使用Nginx缓存,可以使用以下配置消除它的影响

1
proxy_ignore_headers Cache-Control;

4.3. 缓存使用情况

为了方便测试,首先将过期时间调整为10秒:

1
proxy_cache_valid 200 304 10s;

第一次访问,Nginx-Cache=MISS,说明此时还没有缓存;
第二次访问,Nginx-Cache=HIT,此时命中缓存;
第三次访问,Nginx-Cache=STALE,此时缓存过期;
第四次访问,Nginx-Cache=HIT,重新命中缓存;

5. 注意事项

5.1. 缓存一致性问题

缓存的使用可能导致数据不一致,尤其是对于动态更新的数据。为了避免这个问题:

  • 可以设置较短的缓存时间;
  • 数据更新后及时清除相关缓存;
  • 通过Etag和Last-Modified头实现缓存的验证机制,确保客户端获取到最新的数据;

5.2. 缓存空间管理

合理设置缓存空间大小和过期时间至关重要:

  • 过大的缓存空间可能导致磁盘占用过高;
  • 过小的空间则可能频繁触发缓存淘汰机制;
  • 建议根据实际业务需求和服务器资源情况,动态调整缓存空间和过期策略;

5.3. 性能监控与调优

定期监控 Nginx 缓存的命中率、响应时间等指标,分析缓存对系统性能的影响。
根据监控结果,优化缓存配置,如调整缓存键规则、缓存时间等,以达到最佳性能效果。