当前位置: 首页 > news >正文

Nginx本地缓存API

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

你是否面临这些 API 性能瓶颈?

  • ❌ 商品详情页接口 QPS 高达 10w+,后端扛不住
  • ❌ 用户配置接口(低频变更)被频繁调用
  • ❌ 后端服务偶发超时,导致用户体验卡顿
  • ❌ 活动接口在大促时直接被打垮

Nginx 本地缓存(proxy_cache)是官方提供的服务端缓存机制,专为 API 设计:
将 JSON 响应缓存到本地磁盘
相同请求直接返回缓存,绕过后端
实现“缓存托底”——后端挂了也能返回旧数据

本文将手把手教你为 API 接口配置 Nginx 本地缓存,并提供生产级最佳实践


二、核心原理:proxy_cache 如何缓存 API?

💡关键点

  • 缓存存储在本地磁盘(可配置内存)
  • 默认缓存键:$scheme$proxy_host$request_uri
  • 支持按状态码(200/404)控制缓存策略

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

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

http { # 定义 API 缓存区域 proxy_cache_path /var/cache/nginx/api levels=1:2 # 目录层级(防单目录文件过多) keys_zone=api_cache:100m # 共享内存区(100MB ≈ 80万 key) inactive=10m # 10分钟未访问则删除 max_size=5g # 最大缓存 5GB use_temp_path=off; # 关键!避免临时文件拷贝 # 创建目录 # mkdir -p /var/cache/nginx/api && chown nginx:nginx /var/cache/nginx/api }

步骤 2:在 API 路径启用缓存

server { listen 80; server_name api.example.com; # 商品详情接口(高频读、低频写) location /api/product/ { proxy_cache api_cache; proxy_cache_key "$host|$request_uri"; # 自定义 key # 仅缓存 200 响应,有效期 5 分钟 proxy_cache_valid 200 5m; # 忽略后端 Cache-Control 头(强制由 Nginx 控制) proxy_ignore_headers Cache-Control Expires Set-Cookie; # 透传真实 IP proxy_set_header X-Real-IP $remote_addr; proxy_pass http://product_backend; } # 用户配置接口(几乎不变) location /api/user/config/ { proxy_cache api_cache; proxy_cache_valid 200 1h; # 缓存 1 小时 proxy_pass http://user_backend; } }

步骤 3:定义上游服务

upstream product_backend { server 10.0.0.10:8080; server 10.0.0.11:8080; } upstream user_backend { server 10.0.0.20:8080; }

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

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

# 添加缓存状态头 add_header X-Cache-Status $upstream_cache_status always; # 可能的值: # - MISS:未命中 # - HIT:命中 # - EXPIRED:过期(正在后台更新) # - BYPASS:跳过缓存(如 POST 请求)

4.2 跳过缓存(调试或写操作)

# POST/PUT/DELETE 不缓存 if ($request_method ~* ^(POST|PUT|DELETE)$) { set $nocache "1"; } # 请求带 ?nocache=1 时不走缓存 if ($arg_nocache = "1") { set $nocache "1"; } proxy_cache_bypass $nocache; proxy_no_cache $nocache;

4.3 按用户隔离缓存(个性化 API)

# 为登录用户缓存个性化内容 proxy_cache_key "$host|$request_uri|$cookie_user_id"; # 或从 Token 中提取用户 ID(需 OpenResty) # proxy_cache_key "$host|$request_uri|$jwt_claim_user_id";

五、生产级最佳实践:API 专属优化

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

location /api/campaign/ { proxy_cache api_cache; proxy_cache_valid 200 30s; # 关键!后端错误时使用过期缓存 proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; # 后台更新缓存(避免请求堆积) proxy_cache_background_update on; proxy_pass http://campaign_backend; }

效果

  • 后端宕机 → 用户仍能看到最近一次活动数据
  • 大促期间服务 SLA 从 95% 提升至99.95%

5.2 性能优化建议

项目推荐值说明
缓存目录SSD 磁盘避免 HDD I/O 瓶颈
inactive≥ 业务更新周期商品详情设 5-10 分钟
max_size≤ 磁盘 80%防止占满磁盘
keys_zone100MB 起每 1MB ≈ 8000 个 key

5.3 清理缓存(Purging)

Nginx 开源版不支持 PURGE,可通过脚本清理

# 根据 URL 计算缓存 key 的哈希(需与 proxy_cache_key 一致) KEY="api.example.com|/api/product/123" HASH=$(echo -n "$KEY" | openssl md5 | cut -d' ' -f2) # 删除缓存文件 LEVEL1=${HASH: -1} LEVEL2=${HASH: -3:2} rm -f /var/cache/nginx/api/$LEVEL1/$LEVEL2/$HASH # 重载 Nginx(非必须,但推荐) nginx -s reload

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


六、验证与监控

6.1 检查缓存是否生效

curl -I http://api.example.com/api/product/123 # 查看响应头 # X-Cache-Status: HIT

6.2 监控缓存指标

# 查看缓存目录大小 du -sh /var/cache/nginx/api # 日志记录缓存状态 log_format api_cache '$remote_addr - $upstream_cache_status [$time_local] ' '"$request" $status $body_bytes_sent'; access_log /var/log/nginx/api_cache.log api_cache;

七、常见问题排查

问题原因解决
缓存未生效后端返回Cache-Control: no-cache添加proxy_ignore_headers Cache-Control;
缓存穿透大量唯一 ID(如 /api/user/随机字符串)规范 API 设计,或返回 404
磁盘写满max_size未设置设置合理的max_size
中文乱码编码不一致确保后端返回 UTF-8

八、结语

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

http://www.jsqmd.com/news/608774/

相关文章:

  • 程序控制结构
  • Altium AD20差分对走线实战:如何用交互式布线快速搞定高速信号线
  • ABAQUS用户子程序进阶指南——UMAT参数详解与实战配置
  • 通俗秒懂:储能控制器在电网调频中的关键作用与实现原理
  • 软件需求工程教案
  • Golang如何设置HTTP路由_Golang HTTP路由教程【实用】
  • 一张图看懂巴菲特 48 年投资帝国:知识图谱效果全展示
  • 别再手动配环境了!用ModelScope官方镜像5分钟搞定AI模型运行环境(附最新CPU/GPU镜像地址)
  • 【转载】ROS 中 CMakeLists.txt 文件使用的讲解与总结
  • Workstation 避坑指南:网络总连不上?深度解析常见网络配置故障与底层排错逻辑
  • 【计算机网络八股】【欧弟求职】TCP相关
  • 一台服务器跑4个独立站,我是怎么做到的?
  • 魔兽争霸III终极优化指南:免费解决老游戏在现代电脑的兼容性问题
  • RFID智能柜-RFID智能柜公司推荐 - 聚澜智能
  • 如何用 every 判断数组是否所有元素都满足特定条件
  • Spring AI 1.x 系列【25】结构化输出案例演示
  • XOutput完整指南:如何将旧游戏手柄转换为Xbox控制器
  • GeoAI赋能智慧城市:从交通优化到环境监测的实战解析
  • 别再只用‘auto’模式了!深入Halcon条码识别参数:手把手教你调优barcode_width_min与扫描线提升识别率
  • ZYNQ FPGA固化文件生成与烧录全流程详解
  • Springboot 实现多数据源(PostgreSQL 和 SQL Server)连接康
  • 基于改进A*算法与DWA融合策略的机器人路径规划仿真研究:全局规划与局部避障的综合性能分析
  • c++如何利用C++23的std--expected重构文件操作的错误检查代码【实战】
  • Node Modules Inspector:可视化你的Node.js依赖关系,5分钟快速上手指南
  • 电容滤波实战:如何为你的MCU电源选择100nf和1uf电容组合?
  • 企业级 Agent 治理平台:公司用数字帮手的必备管家
  • 三步解锁网易云加密音乐:ncmdump让NCM文件全设备自由播放
  • FanControl:三招告别电脑噪音,打造你的专属静音散热系统
  • uni-app动态修改tabbar uni-app如何根据权限显示不同的tab
  • 写段代码教会你什么是HOOK技术?HOOK技术能干什么?刎