轮询本身不参与缓存决策,只按顺序分发请求;真正决定缓存行为的是proxy_cache配置和响应头逻辑,nginx先查本地缓存,命中则直接返回,未命中才触发轮询转发。

轮询本身不参与缓存决策,它只管把请求按顺序发给后端;真正决定“要不要走缓存、走哪层缓存”的,是 proxy_cache 配置 和 响应头控制逻辑。两者配合得当,轮询才能既均衡流量,又不破坏缓存效率。
轮询和 proxy_cache 的执行先后关系
Nginx 在收到请求后,先检查本地 proxy_cache 是否命中:如果命中且未过期,直接返回缓存内容,根本不会触发 upstream 调度;只有未命中或失效时,才按轮询规则选一台后端服务器转发请求。这意味着:
- 高频静态资源(如 CSS/JS/图片)一旦被 Nginx 缓存,后续请求完全绕过轮询,不产生后端压力
- 动态接口若没配置 cache 或缓存时间极短,每次请求都会走轮询,容易暴露冷热不均问题
- 同一 URL 在不同时间可能由不同后端处理(比如缓存刚失效),但只要 Nginx 层缓存有效,用户感知不到后端切换
避免轮询削弱缓存效果的关键配置
默认轮询是无状态的,容易让相同 URI 分散到多台后端,导致每台都重复建本地缓存。要提升整体缓存复用率,需主动约束分发行为:
- 对缓存友好型接口,改用
hash $request_uri consistent替代纯轮询,保证相同路径总落到同一节点 - 静态资源路径统一加
proxy_cache_valid 200 206 304 1h,并设proxy_cache_key $uri,避免因 query 参数或 header 差异导致缓存分裂 - 在
upstream块中不混用ip_hash或weight,保持轮询逻辑干净,便于后续做一致性哈希扩展
缓存失效期与轮询协同的实操要点
轮询不关心缓存状态,但后端节点的缓存水位会影响整体性能。例如某台刚重启,所有落到它的请求都会回源——而轮询并不会因此少分请求给它:
- 所有后端应统一设置相对 TTL(如
Cache-Control: max-age=60),避免各节点老化节奏错乱 - 启用
proxy_cache_use_stale updating,允许后台更新缓存时仍返回旧内容,减少轮询期间的空窗抖动 - 搭配健康检查(
max_fails=2 fail_timeout=15s),快速剔除缓存未预热或响应变慢的节点,防止请求持续打空
监控验证是否真“缓存+轮询”协同生效
不能只看 upstream 各节点请求数差不多,就认为缓存策略成功。关键要看实际缓存行为:
- 开启日志字段
$upstream_addr和$sent_http_cache_control,确认“哪个后端响应了” + “它声明的缓存时效” - 统计
$upstream_cache_status(MISS/HIT/EXPIRED/STALE),区分是 Nginx 缓存未命中,还是后端压根没返回可缓存响应 - 对比 LB 层与 Edge 层的
proxy_cache_valid和cache_path配置是否一致,尤其 CDN 场景下必须两端策略对齐











