灰度发布平滑切换的关键是路径隔离、缓存策略协同与服务端动态路由;通过哈希文件名实现缓存隔离,静态资源设1年缓存且immutable,html禁用长期缓存并配合vary头与sub_filter动态替换路径。

灰度发布期间,浏览器缓存的平滑切换关键不是“清掉旧缓存”,而是让新旧静态资源在用户侧并存、按需加载、互不干扰——靠的是路径隔离 + 缓存策略协同 + 服务端动态路由,而不是强制刷新或版本号拼接。
用带哈希的文件名实现天然缓存隔离
构建时生成唯一内容哈希(如 app.a1b2c3d4.js),确保每次变更都产生新 URL。Nginx 不需要做任何判断,只需统一为静态资源设置长期缓存:
location ~* \.(js|css|woff2|png|jpg|gif)$ { expires 1y; add_header Cache-Control "public, immutable"; }-
浏览器看到
app.a1b2c3d4.js和app.f5e6d7c8.js是两个完全独立资源,不会互相覆盖 - 灰度用户加载新版 HTML 时自然引用新哈希路径,旧用户仍走旧路径,无冲突
HTML 必须禁用长期缓存,由 Nginx 控制版本分发
index.html 这类入口文件不能被浏览器缓存太久,否则用户卡在旧 HTML 就永远引不到新 JS:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
location = /index.html { expires -1; add_header Cache-Control "no-cache, must-revalidate, max-age=0"; }- 这样每次访问都会向 Nginx 发起请求,Nginx 可根据 Cookie、Header 或 IP 决定返回哪个版本的 index.html
- 配合
sub_filter动态替换资源路径(如把/js/app.js替成/js/app.v2.js),再设极短缓存(expires 10s;),实现灰度 HTML 的快速收敛
通过 Vary 响应头避免 CDN 或代理缓存错乱
当 Nginx 根据请求特征(如 Cookie: user_type=canary)返回不同版本 HTML 时,必须声明差异化依据:
-
add_header Vary "Cookie";或add_header Vary "X-Release"; - 否则 CDN 或中间代理可能把灰度版 HTML 缓存后返回给所有用户,造成版本污染
- 若同时依赖多个字段(如 Cookie + User-Agent),可写成
Vary: Cookie, User-Agent
前端资源路径可由服务端注入,不硬编码在构建产物中
避免前端打包时就写死资源域名或路径,把控制权交还 Nginx:
- HTML 中用占位符,如
<script src="/js/app.js"></script> - Nginx 在响应时用
sub_filter按灰度规则替换成实际路径:sub_filter '/js/app.js' '/js/app.v2.a1b2c3d4.js'; - 配合
sub_filter_once off;支持多处替换,且只作用于 HTML 响应体,不影响二进制资源










