Nginx通过map指令实现基于Cookie的自定义负载均衡路由,核心是将cookie值(如canary=1)映射为upstream分组名,再由proxy_pass动态转发;map必须置于http块顶层,变量名以$开头,需显式default分支,且proxy_pass仅支持引用同名upstream。
用 Nginx 的
指令实现基于 Cookie 值的自定义负载均衡
路由
,核心是把用户标识(如
、
、
)从请求中提取出来,映射为一个可被
直接引用的上游分组名,从而让不同用户固定或按策略走向不同后端集群。它不是传统意义上的“轮询/加权”,而是语义化、可编程的路由控制,轻量且无需重启即可生效。
必须放在 http 块顶层定义
是 Nginx 的全局变量映射指令,只能出现在
块内,且必须在所有
和
声明之前。放错位置会直接报错
。
正确位置示例:打开
,在
开头后、第一个
前插入 map 配置
变量名必须以
开头,如
,且只能引用内置变量(如
、
)
未携带目标 Cookie 时,
值为空字符串
,不是未定义 —— 所以
分支不能省略
精准匹配 Cookie 字段值
Cookie 是原始字符串(如
),Nginx 不自动解析键值对。推荐两种安全写法:
灵活路由的PHP库
灵活路由的PHP库
下载
用
直接获取名为
的 Cookie 值(Nginx 自动提取),适合约定明确的单值字段,例如:
map $cookie_canary $backend_group {default "prod";~^(1|true|on|yes)$ "canary";}
用
配合正则完整匹配,适合多字段混杂或需复杂判断的场景,例如:
map $http_cookie $backend_group {default "prod";~*canary=1(;|$) "canary";~*uid=(abc123|def456)(;|$) "gray";}
注意
表示忽略大小写,
防止
被误匹配
绑定 upstream 并动态 proxy_pass
映射出变量后,需提前定义对应名称的
块,并在
中用
引用:
每个
名称必须与
输出值完全一致(区分大小写),例如输出
,就必须有
可在
内使用
、
等参数做细粒度控制,比如灰度集群设
控制流量比例
后不能跟路径(如
),否则变量拼接会失败;路径应在
或后端处理
容器化环境适配要点
在 Docker 或 Kubernetes 中部署时,关键是要让配置可注入、可热更新、不耦合镜像:
将
配置单独抽成
,通过 ConfigMap 挂载到
下,避免修改主配置文件
启用
热重载机制,配合健康检查探测配置有效性,避免 reload 失败导致服务中断
若用 Ingress-nginx,原生不支持自定义
,需替换其
或改用
注解 + 后端服务隔离方式
灰度 Cookie 建议设
、
(7天),确保跨路径、跨刷新仍有效
mapuidcanaryversionproxy_passmaphttp { ... }serverupstreamunknown directive "map"/etc/nginx/nginx.confhttp {server$$backend_group$cookie_canary$http_cookie$cookie_xxx""defaultcanary=1; uid=abc123; theme=dark$cookie_xxxxxx$http_cookie~*(;|$)canary=10upstreamlocationproxy_pass http://$backend_groupupstreammap"canary"upstream canary { ... }upstreamweightmax_failsweight=5proxy_passhttp://$backend_group/locationmapgray-map.conf/etc/nginx/conf.d/nginx -s reloadmapnginx-templatecanary-by-cookiePath=/Max-Age=604800