nginx多机房容灾需权重适配物理拓扑、upstream_hash保障会话亲和、proxy_next_upstream与健康检查提升韧性,dns层gslb解耦可进一步优化。

单纯靠Nginx默认轮询无法在多机房容灾中实现真正流量均摊——它不感知机房带宽、延迟或负载差异,直接轮询容易导致某机房过载而另一机房闲置。关键是要让轮询“适配物理拓扑”,通过权重控制、会话亲和与健康保障三者协同,才能兼顾均匀性与可用性。
用weight+max_fails做机房级粗粒度分流
轮询本身无地域意识,必须靠weight将“逻辑轮询”映射到“物理承载力”。例如北京机房出口带宽是广州的1.7倍,后端节点数却相同,就不能等权配置。
- 按实际服务能力反向设权:北京每台server设weight=10,广州每台设weight=6
- 搭配max_fails=3 fail_timeout=30s,自动剔除短时异常节点,避免单点故障拖累整机房流量承接
- 总权重比即为理论流量分配比(如40:12≈77%:23%),比简单数量轮询更贴近真实资源水位
用upstream_hash保障会话亲和,防止跨机房重定向
若用户登录态、文件上传或本地缓存依赖特定机房,强制固定路由比均匀更重要。此时轮询退为辅助,hash成为主路由依据。
- 使用hash $remote_addr consistent,基于客户端IP哈希并启用一致性,增减节点时大部分用户仍落在原机房
- 配合weight设置,既保证用户不漂移,又确保两个机房整体承接比例可控
- 避免用$request_uri等易变变量做hash,否则同一用户不同请求可能散落不同机房
加健康检查与proxy_next_upstream提升容灾韧性
多机房场景下,单个节点故障常伴随网络抖动或延迟飙升,仅靠轮询跳过down节点远远不够。
- 配置proxy_next_upstream error timeout http_500 http_502 http_503 http_504,一次失败立即换节点,避免慢请求堆积
- 启用health_check interval=5 fails=2 passes=2(需http_upstream_module支持),主动探测各机房节点可用性
- 对广州等弱链路机房,可适当调高fail_timeout(如60s),避免因瞬时RT高被误摘
进阶建议:前置DNS层解耦,Nginx专注单机房内均衡
当机房间网络质量差异大、延迟不稳定时,把调度决策前移到DNS层更稳妥。
- 用GSLB(如PowerDNS+GeoIP)按用户地理位置解析:北京用户→bj.example.com,广州用户→gz.example.com
- Nginx只负责各自机房内部的轮询或加权轮询,彻底规避跨机房调度难题
- 该方案运维清晰、故障隔离强,适合对SLA要求高的生产环境











