Nginx的map指令可基于$http_authorization头提取灰度标识(如GrayKey或Bearer Token中的关键词),映射为$backend_group变量,再通过proxy_pass动态路由至对应upstream;map须置于http块内,支持~*正则忽略大小写匹配,需设default兜底,且变量名须与upstream名称严格一致。

Nginx 的 map 指令可以将请求中的任意变量(比如 $http_authorization)映射为自定义变量,再结合 upstream 或 proxy_pass 实现基于 Authorization 头的灰度路由——无需改业务代码,也不依赖外部服务。
提取并解析 Authorization 头中的灰度标识
map 本身不支持正则捕获组直接赋值,但可通过正则匹配 + 命名捕获(Nginx 1.11.6+)或分步匹配提取关键字段。常见做法是约定 Token 中携带灰度信息,例如:
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJncmFkZSI6ImJsdWUiLCJzdWIiOiIxMjM0NTY3ODkwIn0...- 或更轻量:直接在 Basic 或自定义 Scheme 中嵌入,如
GrayKey user:blue-v2
推荐先用正则从 $http_authorization 中提取关键词(如 blue-v2、green-canary),再映射到后端分组:
map $http_authorization $backend_group {
~*GrayKey\s+\S+:(\S+) $1; # 匹配 GrayKey user:blue-v2 → $backend_group = blue-v2
~*Bearer\s+[A-Za-z0-9\-_]+\.([a-zA-Z0-9\-_]+)\. $1; # 简单 JWT payload 第二段解码前取子串(需配合 base64 安全约定)
default production;
}注意:map 块必须放在 http 块中,且不能嵌套;正则匹配区分大小写,~* 表示忽略大小写。
定义多套 upstream,按灰度组动态选择
把不同灰度环境的后端服务定义为独立 upstream,名称与 $backend_group 值对齐:
upstream production {
server 10.0.1.10:8080;
}
<p>upstream blue-v2 {
server 10.0.1.11:8080;
}</p><p>upstream green-canary {
server 10.0.1.12:8080 weight=2;
server 10.0.1.13:8080;
}然后在 location 中使用变量拼接 upstream 名称(Nginx 1.19.5+ 支持变量 upstream):
location /api/ {
proxy_pass http://$backend_group;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}若 Nginx 版本较旧(map 映射到具体 proxy_pass 地址:
map $backend_group $upstream_addr {
blue-v2 "10.0.1.11:8080";
green-canary "10.0.1.12:8080,10.0.1.13:8080";
default "10.0.1.10:8080";
}
<h1>然后在 location 中:</h1><p>proxy_pass <a href="https://www.php.cn/link/3b3f06f94891410cd5cec559abe7cff8">https://www.php.cn/link/3b3f06f94891410cd5cec559abe7cff8</a>;增强可靠性:兜底与调试机制
灰度逻辑一旦出错容易导致全量流量误入测试环境,建议加入安全控制:
- 添加
if ($backend_group !~ ^(production|blue-v2|green-canary)$) { return 400; }拦截非法灰度值 - 用
log_format记录$backend_group和原始$http_authorization,便于排查映射失败原因 - 灰度组名避免含特殊字符(如
/、、:),否则可能破坏upstream解析或日志格式 - Authorization 头可能被代理或 WAF 清洗,可在
log_format中加$http_authorization字段确认是否送达 Nginx
验证与上线建议
上线前务必本地验证映射逻辑:
- 用
curl -H "Authorization: GrayKey user:blue-v2" http://test.example.com/api/测试路由是否命中blue-v2后端 - 检查 Nginx error log 是否有
upstream resolver或invalid URL prefix类错误 - 灰度初期可配合
limit_req限制某灰度组的 QPS,防止突发流量冲击测试服务 - 生产环境建议将灰度逻辑和主配置分离,用
include gray-routing.conf;管理,便于灰度开关


















