nginx缓存策略实现平滑迁移的核心是控制新旧内容可见节奏,通过浏览器缓存(静态资源设immutable、html禁长期缓存)与proxy缓存(多上游路由、错误响应缓存、差异化key)协同隔离后端变更影响,并辅以purge清理、缓存状态头、灰度验证及防污染机制。

通过 Nginx 配置缓存策略实现平滑业务迁移,核心不是“让旧服务多活一阵”,而是“控制新旧内容的可见节奏”——用缓存作为缓冲层,隔离后端变更对终端用户的影响。关键在于分清两类缓存的作用域,并协同使用。
浏览器缓存:控制用户侧更新节奏
迁移期间最怕用户卡在旧版本 JS/CSS 里,导致界面错乱或接口不兼容。此时不能依赖 URL 版本号(如 /app.js?v=2.1)就万事大吉,还要确保浏览器真正按需拉新资源:
- 静态资源(.js、.css、.woff2、.png)统一加 immutable:
add_header Cache-Control "public, immutable"; —— 这样带查询参数的请求不会被误判为新资源,同时避免强制刷新仍走本地缓存 - HTML 文件(index.html、entry.html)禁用长期缓存:
expires -1; 或 add_header Cache-Control "no-cache, must-revalidate"; —— 确保每次访问都向 Nginx 发起请求,由 Nginx 决定返回新版还是旧版后端内容 - 若旧 HTML 已发布且无法立即下线,可在 Nginx 中用 sub_filter 动态替换资源路径,配合短缓存(如 expires 10s;),实现灰度切换
Proxy 缓存:隔离后端切换抖动
当流量逐步切到新服务时,后端响应可能不稳定或返回不同状态码。proxy_cache 能吸收这些波动,不让用户感知:
- 为新旧两套后端分别定义 upstream,并用 map 匹配路径或 header 决定走哪条链路;再配合 proxy_cache_valid 500 502 503 504 10s;,让错误响应也缓存极短时间,避免雪崩式重试
- 使用 proxy_cache_use_stale error timeout updating http_500;,在后台更新缓存失败或超时时,仍可返回过期但可用的内容,保障可用性
- 设置差异化 key:
proxy_cache_key "$host$request_uri$cookie_user$arg_v"; —— 加入版本参数 arg_v 后,同一 URL 可并存 v1 和 v2 的缓存项,方便灰度验证
缓存清理与灰度验证机制
迁移不是全量开关,需要可观测、可回退:
- 启用 purge 模块,配置独立 location 处理手动清理:
location ~ /purge(/.*)? { allow 127.0.0.1; deny all; proxy_cache_purge my_cache $host$1$is_args$args; } - 在响应头中暴露缓存状态:
add_header X-Cache-Status $upstream_cache_status; —— HIT 表示命中,MISS 表示首次加载,STALE 表示返回过期内容,便于前端埋点或日志分析 - 对新服务路径(如 /api/v2/)单独设置更短的缓存周期(proxy_cache_valid 200 60s;),快速验证稳定性;旧路径(/api/v1/)保留长缓存(proxy_cache_valid 200 1h;),降低压测压力
避免缓存污染与状态错乱
动态内容混入静态缓存,或未识别的响应头绕过缓存,是迁移期高频故障点:
- 默认情况下,Nginx 不缓存含 Set-Cookie 或 Authorization 的响应。若新服务需缓存登录态相关接口,必须显式忽略:
proxy_ignore_headers Set-Cookie;
proxy_cache_use_stale off;(慎用,仅限明确无副作用场景) - 后端若返回 Cache-Control: private 或 no-store,Nginx 默认遵从。如需覆盖,需用 proxy_hide_header Cache-Control; + add_header Cache-Control "public, max-age=60";
- 禁止对健康检查路径(如 /healthz、/readyz)做任何缓存,否则负载均衡器可能误判节点状态。可用 proxy_cache_bypass 1; 强制绕过











