Nginx基于Cookie的静态资源灰度分发通过map指令在请求早期识别gray_version Cookie,动态映射static_prefix变量,并用sub_filter将HTML中{VERSION}占位符替换为对应版本路径,实现零代码侵入、无跳转的轻量灰度。

用 map 指令做基于 Cookie 的静态资源灰度分发,核心是让 Nginx 在请求进入早期就识别用户身份标签,并将资源路径或后端服务动态指向对应版本。它不依赖 Lua、不改业务代码、不增加请求跳转,适合生产环境轻量落地。
一、明确灰度标识与资源组织方式
静态资源灰度不是转发请求,而是控制 HTML 中的 <script></script>、 等标签加载哪个版本的 JS/CSS。因此需提前约定:
- Cookie 键名统一为
gray_version,值如v2、canary、ab-test-2026 - 静态资源按版本隔离存放,例如:
/static/v1/app.js/static/v2/app.js/static/canary/app.js - HTML 模板中资源路径不写死,改用占位符,如
<script src="/static/%7BVERSION%7D/app.js"></script>,由 Nginx 注入实际值
二、在 http 块中定义 map 映射规则
必须放在 http{...} 顶层作用域,不可嵌套在 server 或 location 内:
http {
# 提取 Cookie 并映射为资源路径前缀
map $cookie_gray_version $static_prefix {
default "/static/v1";
"v2" "/static/v2";
"canary" "/static/canary";
~*^ab-test "/static/canary";
~*^v[3-9] "/static/v3";
}
<pre class="brush:php;toolbar:false;"># 同时映射一个用于日志标记的变量(便于排查)
map $cookie_gray_version $gray_tag {
default "v1";
"~.+" "$cookie_gray_version";
}
}
注意:
• 正则匹配用 ~* 忽略大小写,提高容错性
• 顺序从上到下,首个匹配即生效,default 放最后兜底
• 变量名要语义清晰,避免和内置变量冲突
三、在 server 中注入版本路径到 HTML 响应
对 index.html 类主入口文件做响应体替换,把占位符替换成真实路径:
server {
listen 80;
root /usr/share/nginx/html;
<pre class="brush:php;toolbar:false;">location = /index.html {
# 开启子请求替换功能
sub_filter '<script src="/static/%7BVERSION%7D'%20'<script%20src=" sub_filter href="/static/%7BVERSION%7D'%20'<link%20href=" sub_filter_once off sub_filter_last_modified on add_header x-gray-version cache-control must-revalidate try_files><p>}</script>
说明:
• sub_filter 是 Nginx 的文本替换模块,需编译时启用 --with-http_sub_module
• 不建议对所有 HTML 全局替换,只处理主入口,避免干扰模板引擎逻辑
• X-Gray-Version 响应头可用于前端 SDK 日志打标或监控看板聚合
四、配套保障措施
光有分流不够,生产环境还需考虑一致性与可观测性:
-
Cookie 设置时机:由登录接口或首页服务端写入,
Path=/、Secure、SameSite=Lax,避免子路径丢失 -
降级机制:若
$static_prefix解析为空或路径 404,Nginx 默认返回 v1 资源(因default已设),前端无需额外兼容逻辑 -
灰度开关集中管理:可将 map 规则抽成独立配置文件,通过
include gray-rules.conf引入,发布时 reload 即可生效,无需重启 -
验证方式:curl -I http://domain/index.html -b "gray_version=v2" 查看
X-Gray-Version和实际 script src 是否含/v2/
不复杂但容易忽略:静态资源灰度的本质是“内容分发决策前置”,map 提供的是轻量可靠的变量生成能力,真正落地效果取决于 Cookie 的可靠写入、资源目录的规范组织,以及 HTML 渲染链路中占位符的统一约定。











