Nginx 的 map 指令可基于 Cookie 值动态路由至不同 upstream。1. 用正则从 $http_cookie 提取 env 值并映射为 $backend_env;2. 预定义 backend_production/staging/canary 等 upstream;3. 在 location 中用 set 构造 $upstream_name 并 proxy_pass 转发;4. 建议校验 Cookie 值、统一大小写、添加响应头调试,并在缓存中包含 $backend_env。

Nginx 的 map 指令可以将变量(如 Cookie)的值映射为新变量,再结合 proxy_pass 实现按 Cookie 值动态选择上游服务器,无需 Lua 或外部模块。
1. 提取并标准化目标 Cookie 值
Nginx 本身不直接解析 Cookie 字符串,需用正则从 $http_cookie 中提取。例如,要读取名为 env 的 Cookie:
使用 map + 正则捕获,注意空格和分号分隔问题:
map $http_cookie $backend_env {
~*env=([^;]+) $1;
default production;
}说明:
– ~* 表示忽略大小写的正则匹配
– env=([^;]+) 匹配 env=xxx 并捕获等号后、首个分号前的内容
– 若未匹配到,设为默认值 production
2. 定义 upstream 分组对应不同环境
在 http 块中预定义多个 upstream,每个代表一类后端服务:
upstream backend_production {
server 10.0.1.10:8080;
}
<p>upstream backend_staging {
server 10.0.1.11:8080;
}</p><p>upstream backend_canary {
server 10.0.1.12:8080;
server 10.0.1.13:8080;
}建议为每个 upstream 设置健康检查或负载策略(如 least_conn),但非必需。
3. 在 location 中根据映射变量路由请求
利用 $backend_env 变量拼接 upstream 名称,再用 proxy_pass 转发:
server {
listen 80;
server_name example.com;
<pre class="brush:php;toolbar:false;">location / {
# 根据 Cookie 映射结果选择 upstream
set $upstream_name "backend_$backend_env";
proxy_pass http://$upstream_name;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}}
关键点:
– 必须用 set 构造合法 upstream 名(Nginx 不允许 proxy_pass http://backend_$backend_env 直接插值)
– $upstream_name 是运行时变量,Nginx 会动态解析其值
– 若 $backend_env 是 staging,则 $upstream_name 为 backend_staging,匹配上方定义
4. 补充建议与注意事项
- Cookie 值校验:可在 map 中增加白名单限制,避免非法值触发未知 upstream
-
大小写统一:若业务中 Cookie 值大小写混用,可用
lower($1)或upper($1)标准化(需 Nginx ≥ 1.11.8) -
调试技巧:临时添加
add_header X-Backend-Env $backend_env;到 location,用 curl 查看响应头验证是否命中 -
缓存影响:map 是在请求处理早期执行的,不受 proxy_cache 干扰;但若启用缓存,需确保
proxy_cache_key包含$backend_env,否则不同环境可能共用缓存



















