缓存与限流按预期协同工作:缓存对200响应生效,限流在proxy_pass前触发;第一轮单ip 20请求验证未命中时限流生效(5r/s+burst=10)。

直接用工具模拟真实流量组合,观察缓存命中与限流响应是否按预期协同工作。
准备可验证的缓存+限流配置
确保 proxy_cache 和限流模块同时启用且作用于同一 location:
- 在 http 块中定义 cache 区域和限流区域:
proxy_cache_path /var/nginx/cache keys_zone=one:10m levels=1:2 inactive=6h max_size=1g;<br>limit_req_zone $binary_remote_addr zone=api_limit:10m rate=5r/s;
- 在 server 的 location 中同时启用:
location /api/data {<br> proxy_cache one;<br> proxy_cache_valid 200 302 10m;<br> limit_req zone=api_limit burst=10 nodelay;<br> proxy_pass http://backend;<br>} - 关键点:缓存必须对 200 响应生效,限流需在 proxy_pass 前触发(Nginx 处理顺序默认如此)
分阶段构造测试流量
用 wrk 或 ab 分别验证不同行为:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 第一轮(缓存未命中):单 IP 发起 20 个请求,间隔 → 应看到前 5 个请求穿透到后端(cache miss),返回 200 并写入缓存;后续请求若命中缓存,则不触发限流判定(因限流发生在 proxy_pass 阶段,而缓存响应不走该阶段)
- 第二轮(缓存已命中):等待 1 秒后重复请求同一 URL
→ 所有响应应来自缓存,status=200,响应时间极低,且 access_log 中无 proxy_pass 日志,limit_req 计数不增加 - 第三轮(突破限流):用多个 IP(或 --latency + --timeout 调整)发起高频请求
→ 当单 IP 超过 5r/s 且 burst 耗尽时,返回 429(若配了limit_req_status 429),且该响应不进入缓存(Nginx 默认不缓存非 2xx/301/302 响应)
检查关键日志与指标
打开 Nginx 的详细日志,确认行为逻辑:
- 在 log_format 中加入变量:
log_format main '$remote_addr - $request_time $status $upstream_cache_status $limit_req_status'; - 观察字段含义:
•$upstream_cache_status显示 HIT/MISS/EXPIRED/BYPASS
•$limit_req_status显示 PASSED(放行)、REJECTED(被拒)、DELAYED(延迟)
• 若为 429 错误,$upstream_cache_status必为 “-”,说明未进缓存流程 - 用
tail -f /var/log/nginx/access.log | grep -E "(429|HIT|MISS)"实时过滤验证
注意易错点
常见失效原因不是配置写错,而是逻辑冲突:
- 缓存 key 包含了变化参数(如时间戳、随机数),导致永远 MISS → 检查
proxy_cache_key是否稳定 - 后端响应头含
Cache-Control: no-cache或Set-Cookie→ 缓存自动失效,限流仍生效但无法减轻后端压力 - 限流放在 proxy_cache 后(如写在 if 或 rewrite 后)→ 实际不生效,必须确保 limit_req 在 location 主干中紧邻 proxy_pass 上方
- burst 过大且配了 nodelay → 看似没限流,其实是把突发全放行了,需结合业务峰值合理设 burst=日常 QPS×0.2~0.3










