加权轮询需结合geo/map/分组upstream与健康检查实现跨地域调度:按地域分设upstream组,用geo识别用户区域,map映射目标组,权重反映真实qps能力,并配主动健康检查与fallback降级。

加权轮询本身不直接支持“跨地域”调度,它只是在同一个 upstream 组内按权重分发请求。要实现多机房跨地域的加权流量调度,必须把地域感知、健康状态和权重控制三层能力组合起来用——不是靠单一指令,而是靠 geo + map + 分组 upstream + 主动探测的协同。
按地域划分 upstream 组,不混写在同一个池里
每个机房单独定义一个 upstream,明确隔离网络边界和运维责任:
upstream backend_bj { server 10.1.1.10:8080 weight=5; server 10.1.1.11:8080 weight=5; }upstream backend_sh { server 192.168.2.20:8080 weight=3; server 192.168.2.21:8080 weight=3; }-
upstream backend_sz { server 172.16.3.30:8080 weight=2; }(仅作兜底,权重最低)
避免把三地节点全塞进一个 upstream——那样无法做地域优先,也容易因异地延迟高导致连接堆积或超时误判。
用 geo + map 动态绑定用户到对应机房组
先识别用户来源,再映射到目标 upstream:
- 在
http块中用geo指令粗略归类 IP 所属大区:geo $client_region { default "other"; include /etc/nginx/geoip.conf; } - 再用
map把区域映射为 upstream 名称:map $client_region $target_upstream { "cn_beijing" "backend_bj"; "cn_shanghai" "backend_sh"; "cn_guangdong" "backend_sz"; default "backend_bj"; } - 在
location中使用:proxy_pass http://$target_upstream;
注意:公网 IP 地理归属常不准,建议配合 CDN 透传的 X-Real-Region 或登录态中的用户常驻地信息做 fallback 判断。
权重设得有依据,不是拍脑袋
权重比例应反映真实服务能力,例如:
- 北京机房单节点稳态 QPS 是 1500,上海是 900,深圳是 600 → 权重比可设为 5:3:2
- 若深圳只用于读请求兜底,日常只想承接 5% 流量,就把它所有节点
weight=1,其他机房统一设weight=10,再配合max_fails=2 fail_timeout=30s防误剔 - 上线前务必实测单点极限:用
wrk -t4 -c100 -d30s http://node/health看吞吐,反推合理权重
必须配健康检查,否则权重再准也没用
跨地域链路不稳定,仅靠连接失败被动剔除太慢。推荐组合策略:
- 基础层:每个
server行后加max_fails=3 fail_timeout=20s - 主动层:用
health_check interval=5 rise=2 fall=3(需 Nginx Plus)或开源版搭配lua_healthcheck模块 - 探活路径独立:比如北京机房用
/health?site=bj,不与主业务共用接口,防偶发慢导致误判 - 节点恢复后自动回归,无需人工干预
没有健康检查的加权调度,就是把流量往可能已宕机的机房硬送。
留好 fallback 路径,本地全挂时不中断
不能只靠 map 映射,还要有降级兜底机制:
- 定义一个全局备用组:
upstream backend_fallback { server 192.168.2.20:8080; server 172.16.3.30:8080; } - 在 location 中用
error_page 502 503 504 = @fallback,并在@fallback里proxy_pass http://backend_fallback; - 更优做法:用
map嵌套判断,例如当$bj_health == "down"且$sh_health == "down",则$target_upstream = "backend_sz"
真正的容灾不是“能不能切”,而是“切得快、切得准、切完不抖”。











