Nginx本地缓存

一、前言:为什么需要 Nginx 本地缓存?

你是否面临这些痛点?

  • ❌ 后端服务压力大,大量重复请求打到应用层
  • ❌ 静态资源(图片、JS、CSS)频繁回源
  • ❌ 接口响应慢,用户体验差
  • ❌ 后端宕机时,整个服务不可用

Nginx 本地缓存(proxy_cache) 是官方提供的服务端缓存机制 ,它能:

将后端响应缓存到本地磁盘或内存

相同请求直接返回缓存,绕过后端

实现"缓存托底"------后端挂了也能返回旧数据

本文将带你从零配置 proxy_cache,并提供生产级最佳实践


二、核心原理:proxy_cache 如何工作?

💡 关键点

  • 缓存存储在本地磁盘(可配置内存)
  • 缓存键(key)默认基于 $scheme$proxy_host$request_uri
  • 支持按状态码、Header 控制是否缓存

三、基础配置:5 步开启 Nginx 缓存

步骤 1:定义缓存区域(http 块)

Lua 复制代码
http {
    # 定义缓存路径和参数
    proxy_cache_path /var/cache/nginx 
        levels=1:2                # 目录层级(防单目录文件过多)
        keys_zone=my_cache:100m   # 共享内存区名:大小(存放 key 和元数据)
        inactive=60m              # 60分钟未访问则删除
        max_size=10g              # 磁盘最大缓存大小
        use_temp_path=off;        # 直接写入缓存目录,避免临时文件拷贝

    # 创建缓存目录并授权
    # mkdir -p /var/cache/nginx && chown -R nginx:nginx /var/cache/nginx
}

🔍 参数详解

  • levels=1:2:生成两级子目录(如 /a/bc/abcdef...),避免单目录 inode 耗尽
  • keys_zone:1MB 内存约可存 8000 个 key
  • use_temp_path=off必须关闭,否则性能下降 30%+

步骤 2:在 server/location 启用缓存

Lua 复制代码
server {
    listen 80;
    server_name api.example.com;

    location / {
        # 启用缓存,使用名为 my_cache 的区域
        proxy_cache my_cache;

        # 设置缓存 key(可自定义)
        proxy_cache_key "$host$request_uri";

        # 哪些状态码响应可以被缓存
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 404 1m;
        proxy_cache_valid any 5m;

        # 透传 Host 和真实 IP
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

        proxy_pass http://backend;
    }
}

步骤 3:定义上游服务

Lua 复制代码
upstream backend {
    server 10.0.0.10:8080;
    server 10.0.0.11:8080;
}

四、高级配置:精准控制缓存行为

4.1 自定义缓存 Key

Lua 复制代码
# 按用户 ID + URL 缓存(个性化内容)
proxy_cache_key "$host|$request_uri|$cookie_user_id";

# 忽略查询参数中的 token(避免缓存爆炸)
proxy_cache_key "$host|$uri";

4.2 缓存状态透传(用于监控)

Lua 复制代码
# 添加缓存状态头
add_header X-Cache-Status $upstream_cache_status;

# 可能的值:
# - MISS:未命中
# - HIT:命中
# - EXPIRED:过期(正在更新)
# - BYPASS:强制跳过缓存

4.3 强制跳过缓存(调试用)

Lua 复制代码
# 请求带 nocache=1 时不走缓存
if ($arg_nocache = "1") {
    set $nocache "1";
}
proxy_cache_bypass $nocache;
proxy_no_cache $nocache;

五、生产级最佳实践

5.1 缓存托底(后端宕机时返回旧数据)

Lua 复制代码
location /api/ {
    proxy_cache my_cache;
    proxy_cache_valid 200 5m;
    
    # 即使后端返回 5xx,也允许使用过期缓存
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
    
    # 后端挂了?直接返回 stale(过期但可用)缓存
    proxy_cache_background_update on;  # 后台更新缓存
    
    proxy_pass http://backend;
}

效果

  • 后端宕机 → 用户仍能看到最近一次有效数据
  • 服务 SLA 从 99% 提升至 99.99%

5.2 性能优化建议

项目 推荐值 说明
缓存目录 SSD 磁盘 避免 HDD I/O 瓶颈
keys_zone 100~500MB 根据 QPS 调整
max_size ≤ 磁盘 80% 防止占满磁盘
inactive ≥ 业务更新周期 避免频繁重建

5.3 清理缓存(Purging)

Nginx 开源版不支持 PURGE,可通过删除文件 + reload实现:

bash 复制代码
# 删除特定 URL 缓存(需知道 key 的哈希值)
rm -f /var/cache/nginx/a/bc/abcdef123456...

# 或清空整个缓存
rm -rf /var/cache/nginx/*
nginx -s reload

💡 企业方案 :使用 Nginx Plus 的 proxy_cache_purge 指令。


六、验证与监控

6.1 检查缓存是否生效

bash 复制代码
curl -I http://api.example.com/user/profile
# 查看响应头
# X-Cache-Status: HIT

6.2 监控缓存指标

bash 复制代码
# 查看缓存目录大小
du -sh /var/cache/nginx

# 统计缓存文件数
find /var/cache/nginx -type f | wc -l

# 日志记录缓存状态(access_log)
log_format cache '$remote_addr - $upstream_cache_status [$time_local] '
                 '"$request" $status $body_bytes_sent';
access_log /var/log/nginx/cache.log cache;

七、常见问题排查

问题 原因 解决
缓存未生效 后端返回 Cache-Control: no-cache proxy_ignore_headers Cache-Control; 忽略
磁盘写满 max_size 未设置 设置合理的 max_size
缓存穿透 大量唯一 URL(如带时间戳) 规范 URL,或用 proxy_cache_key 去重
中文乱码 编码不一致 确保后端返回 UTF-8

八、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

相关推荐
CodeMartain5 小时前
Redis为什么快?
数据库·redis·缓存
砍材农夫8 小时前
spring-ai 第四多模态API
java·人工智能·spring
她说..10 小时前
Java 对象相关高频面试题
java·开发语言·spring·java-ee
南汐以墨13 小时前
一个另类的数据库-Redis
数据库·redis·缓存
计算机毕设指导613 小时前
基于SpringBoot校园学生健康监测管理系统【源码文末联系】
java·spring boot·后端·spring·tomcat·maven·intellij-idea
RInk7oBjo13 小时前
spring-事务管理
数据库·sql·spring
希望永不加班13 小时前
SpringBoot 数据库连接池配置(HikariCP)最佳实践
java·数据库·spring boot·后端·spring
yaoyouzhong14 小时前
基于SpringBoot和PostGIS的云南与缅甸的千里边境线实战
java·spring boot·spring
一个有温度的技术博主15 小时前
Redis AOF持久化:用“记账”的方式守护数据安全
redis·分布式·缓存