在高并发Web服务场景中,缓存是提升性能、降低服务器负载的核心手段之一。Nginx作为一款高性能的HTTP服务器和反向代理服务器,不仅能实现浏览器端的缓存策略,还能搭建高效的服务器端缓存集群。本文将从实战角度出发,详细讲解Nginx浏览器缓存与服务器缓存的配置方法。
📝 一、浏览器缓存:减少重复请求的第一道防线
浏览器缓存是指将静态资源(如CSS、JS、图片等)存储在用户本地浏览器中,当用户再次访问同一资源时,直接从本地读取,无需向服务器发起请求。Nginx通过设置Expires、Cache-Control等HTTP响应头来控制浏览器缓存行为。
1. 基于文件类型设置缓存过期时间
Nginx
复制
http { # 定义缓存过期时间变量 map $sent_http_content_type $expires { default off; text/html epoch; text/css max; application/javascript max; image/jpeg max; image/png max; image/gif max; application/pdf max; } server { listen 80; server_name example.com; root /usr/share/nginx/html; index index.html index.htm; location / { expires $expires; try_files $uri $uri/ =404; } } }
- 配置说明 :
map指令根据响应的Content-Type类型设置不同的缓存策略epoch表示立即过期(不缓存),适用于HTML页面max表示设置为最长缓存时间(10年),适用于静态资源off表示不设置Expires头
2. 版本化资源的永久缓存策略
对于带有版本号的静态资源(如app.v2.1.0.js),可以设置永久缓存:
Nginx
复制
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; }
- 关键特性 :
immutable标记告知浏览器资源内容不会改变,无需发起验证请求- 版本化资源更新时通过修改文件名(如
app.v2.1.1.js)实现缓存刷新
📦 二、服务器缓存:反向代理缓存提升后端性能
服务器缓存(也称为反向代理缓存)是指Nginx将后端服务器返回的响应内容存储在本地磁盘或内存中,当有新的请求到达时,直接返回缓存内容,无需转发到后端服务器。
1. 基本的磁盘缓存配置
Nginx
复制
http { # 定义缓存存储路径和参数 proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off; server { listen 80; server_name example.com; location / { proxy_cache my_cache; proxy_cache_key "$host$request_uri$cookie_user"; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; proxy_pass http://backend_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } }
- 核心参数解析 :
proxy_cache_path:定义缓存存储路径和相关参数levels=1:2:创建两级目录结构,避免单目录文件过多keys_zone=my_cache:10m:创建名为my_cache的共享内存区,大小10MBmax_size=10g:缓存最大容量10GB,超出时自动删除最少使用的缓存inactive=60m:60分钟内未被访问的缓存将被删除
proxy_cache_key:定义缓存键的生成规则,包含主机名、请求URI和用户Cookieproxy_cache_valid:根据HTTP状态码设置不同的缓存有效期
2. 内存缓存优化高并发场景
对于需要极致性能的场景,可以将缓存存储在内存中:
Nginx
复制
proxy_cache_path /dev/shm/nginx_cache levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
- 注意事项 :
/dev/shm是Linux系统下的临时文件系统,存储在内存中- 内存缓存容量不宜过大,避免占用过多系统内存
- 重启Nginx或服务器重启后,内存缓存会丢失
🎯 三、高级缓存策略:缓存穿透与缓存击穿的解决方案
在实际应用中,缓存系统可能会遇到缓存穿透、缓存击穿等问题,需要通过Nginx配置进行防护。
1. 限制缓存穿透:过滤无效请求
Nginx
复制
location / { # 禁止缓存不存在的资源 proxy_cache_bypass $http_pragma $http_authorization; proxy_no_cache $http_pragma $http_authorization $arg_nocache; # 限制单个IP的请求频率 limit_req zone=one burst=5 nodelay; proxy_pass http://backend_server; }
2. 应对缓存击穿:设置缓存锁
Nginx
复制
http { proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off; server { listen 80; server_name example.com; location / { proxy_cache my_cache; proxy_cache_lock on; proxy_cache_lock_timeout 5s; proxy_cache_lock_age 10s; proxy_pass http://backend_server; } } }
- 缓存锁作用:当某个缓存键对应的内容过期时,只允许一个请求到达后端服务器更新缓存,其他请求等待缓存更新完成后返回新的缓存内容,避免大量请求同时穿透到后端服务器
📊 四、缓存监控与调试
Nginx提供了丰富的缓存状态信息,可以通过ngx_http_cache_purge_module和ngx_http_stub_status_module模块进行监控和调试。
1. 查看缓存状态
Nginx
复制
server { listen 80; server_name example.com; location /nginx_status { stub_status; allow 127.0.0.1; deny all; } }
访问http://example.com/nginx_status 可以查看Nginx的缓存命中情况:
Active connections: 10
server accepts handled requests
10000 10000 50000
Reading: 0 Writing: 2 Waiting: 8
Cache:
5000 entries, 1000000 bytes stored, 2000000 bytes read
2. 手动清除缓存
广告:需要成品学习源码就上会员源码网,svipm.com,各种源码供您选择
使用ngx_http_cache_purge_module模块可以手动清除指定的缓存内容:
Nginx
复制
http { proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off; server { listen 80; server_name example.com; location ~ /purge(/.*) { allow 127.0.0.1; deny all; proxy_cache_purge my_cache "$host$1$is_args$args"; } } }
发送请求http://example.com/purge/css/app.css 即可清除/css/app.css的缓存内容。
📌 五、总结
Nginx的浏览器缓存和服务器缓存配置是构建高性能Web服务的关键技术。通过合理配置浏览器缓存,可以大幅减少用户端的重复请求;通过搭建服务器缓存集群,可以有效降低后端服务器的负载。在实际应用中,需要根据业务场景选择合适的缓存策略,并结合监控工具不断优化缓存配置。
如果你觉得本文对你有帮助,请点赞、收藏、关注支持一下,后续会分享更多Nginx实战技巧!