在Nginx集群中按APP版本分流,需通过map指令提取User-Agent或X-App-Version中的版本号,映射至对应upstream组,再由proxy_pass动态路由;需定义多套upstream、避免proxy_pass后加路径、记录日志并支持灰度与降级。

直接在 Nginx 集群中实现按 APP 版本分流,核心是提取请求头中的版本标识(如 User-Agent 或自定义 Header),再结合 map 指令做条件映射,最终将流量导向不同 upstream 组。这不是标准负载均衡策略,而是基于请求特征的动态路由,需要配合 upstream 分组与 proxy_pass 精确控制。
提取并识别 APP 版本号
多数移动客户端会在 User-Agent 中携带版本信息,例如:
iOS: "MyApp/3.2.0 (iPhone; iOS 17.5)"
也可要求客户端通过自定义 Header(如 X-App-Version: 2.8.0)传递,更规范、易解析。
在 http 块中使用 map 提取版本前缀或区间:
- 匹配正则提取主版本号:
map $http_user_agent $app_version { ~MyApp/([0-9]+)\. $1; default "unknown"; } - 按语义化版本做分组:
map $http_x_app_version $upstream_group { ~^1\. "v1_backend"; ~^2\. "v2_backend"; ~^3\. "v3_backend"; default "fallback_backend"; }
定义多套后端服务集群
为每个版本维护独立的 upstream 块,便于隔离部署、灰度发布和故障隔离:
upstream v1_backend { server 192.168.1.10:8080; server 192.168.1.11:8080; }-
upstream v2_backend { server 192.168.1.20:8080 weight=3; server 192.168.1.21:8080; }(可叠加权重、健康检查等) -
upstream fallback_backend { server 192.168.1.99:8080; }(兜底集群)
在 location 中动态路由到对应集群
利用上一步生成的 $upstream_group 变量,直接作为 proxy_pass 的目标:
location /api/ { proxy_pass http://$upstream_group; proxy_set_header X-App-Version $http_x_app_version; proxy_set_header X-Routed-To $upstream_group; }- 注意:
proxy_pass后不能加 URI 路径(如/api/),否则变量替换会失效;路径应由后端服务统一处理或用rewrite补全 - 建议开启
proxy_next_upstream,当某组内全部节点不可用时自动降级到 fallback
验证与灰度控制增强
上线前需验证分流逻辑是否准确,同时支持小流量灰度:
- 在日志中记录关键字段:
log_format main '$remote_addr - $upstream_group "$http_x_app_version" $request'; - 用
geo或map+ IP 白名单临时强制某类用户走新版本:map $remote_addr $force_v3 { 192.168.10.5 "v3_backend"; default $upstream_group; } - 配合 Consul 或 Nacos 做动态 upstream 注册,实现版本集群的热更新











