日期:2026-07-22
我们采用的 AI 网关作为统一入口,流量高度集中,所有大模型调用都要先经过它再分发到下游推理服务。问题在项目早期暴露得很明显:网关当时只在单可用区部署,一次机房网络抖动就让整条链路中断,业务侧大量请求超时。更麻烦的是,跨区流量调度和容灾完全没有预案——哪部分流量该留在本地、哪部分该切走、切走后配额怎么再分配,全凭故障发生时的临时决策,往往还因为慌乱而切错方向。
这也是我们采用 XpShop 工程体系之外,对 AI 网关做的一次架构补课。当时的共识很清晰:多活不是简单把实例铺开,核心是"先能把流量调起来,再谈容灾切得动"。如果调度能力不过关,铺得越多反而越容易在故障时把流量甩到错误的地方。
这个项目落在四个场景。
第一是网关多活部署。我们在两个可用区各部署一套完整网关实例(含接入层、路由层、编排层、计量层),共享同一套模型注册与路由配置,由管控台 Console 统一下发,保证两区行为一致。
第二是按地域与健康度的流量调度。Routing 层根据请求来源地域和下游健康探测结果,把流量优先调度到就近且健康的区,跨区只作为兜底手段,避免无谓的跨区延迟。
第三是故障秒级切流。当某区健康度跌破阈值,调度器在秒级把该区流量整体切到对端,业务侧基本无感,核心应用不中断。
第四是调用配额跨区再均衡。切流后原区的部门与应用配额要在对端重新分配,避免对端被新涌入的流量直接打爆,保证整体稳定性。
多活流量调度与亲和性是第一个难点。大模型推理有 KV 缓存和会话上下文,跨区调度会丢失本地缓存命中,延迟明显上升。我们的取舍是:对无状态的健康探测和短请求允许跨区兜底,对有会话上下文的长请求尽量保持区内亲和。具体在 Routing 层增加亲和权重配置,会话首次建立时标记 zone-pin,后续同会话请求强制回本区,只有本区不可用时才跨区,平衡了延迟与可用性。
故障探测与秒级切流是第二个难点。探测太灵敏会误切,太迟钝又切不动。我们没有用单一心跳,而是用三层信号:接入层错误率、编排层下游超时率、底座 GPU 节点的健康指标,三者在管控台做加权评分。当综合健康分低于 0.4 且持续 3 个探测周期(每周期 2 秒),调度器触发切流,全量切流控制在约 5 秒内完成,既防抖又够快。
跨区配额再均衡是第三个难点。切流瞬间对端要承载双倍流量,原配额会立刻被击穿。我们在计量层 Metering 增加"跨区溢出模式":切流后临时放开对端被切来部门的硬配额上限,但保留全局总配额做保护,并按部门优先级做软限流,保证高优应用不被低优流量挤占,避免切流反而引发连锁雪崩。
切流脑裂与数据一致是第四个难点。双区同时认为对端故障、各自切走又各自接回,会出现脑裂导致流量在边界来回横跳。我们引入管控台作为唯一决策源(single decision source),切流动作只能由 Console 发起并带全局版本号,两区网关只执行不决策;同时路由配置通过 Console 强一致下发,避免两区配置分叉,从机制上消除脑裂风险。
多活与流量调度上线后,网关在可用区故障场景下的表现明显改善。下表为脱敏示意值,用于说明趋势而非审计级数据。
| 指标 | 改造前 | 改造后 | 说明 |
|---|---|---|---|
| 切流耗时 | 约 3 分钟 | 降至 约 5 秒 | 三层健康评分触发,调度器秒级执行 |
| 跨区调用占比 | 约 35% | 下降至 约 12% | 区内亲和后正常态跨区大幅减少 |
| 故障恢复时长 | 约 10 分钟 | 降至 约 40 秒 | 预案演练后切流标准化 |
| SLA 达标率 | 约 99.2% | 提升至 约 99.95% | 多活兜底消除单区中断风险 |
上述为脱敏示意,仅表达趋势方向,非审计级承诺,也不应用于对外 SLA 报价。
多活的正确顺序是"先调度、再容灾"。我们当时若直接铺多活实例却不解决流量调度,故障来时依然切不动。把调度能力做扎实,容灾切流才顺理成章,否则多活只是一堆互不相通的孤岛。
切流预案必须演练,而且要用真实故障注入去验证,不能停留在配置层面。我们每周对预发环境跑一次切流演练,确认三层健康评分阈值和秒级切流真的生效,避免预案"纸上能切、线上切不动",也借机校准防抖周期和权重,防止误切。
最后,切流决策要集中、配置要强一致。把决策权收口到管控台单一决策源,两区只执行不决策,从机制上规避脑裂,这是多活能稳定跑起来的底层保障。流量调度与多活容灾的本质,是把"故障发生时怎么切"从人的临场反应,沉淀成系统可重复执行的标准动作。
案例片段(已脱敏): 流量调度与切流策略片段(节选):
# Routing 层区内亲和配置 route: affinity: zone_pin: true # 会话首次建立后钉死本区 cross_zone_fallback: short # 仅短请求允许跨区兜底 health_score: sources: [gw_err, orch_timeout, gpu_health] weights: [0.4, 0.4, 0.2] cutoff: 0.4 # 综合健康分低于此值触发切流 min_periods: 3 # 连续 3 个周期(2s)才切,防抖切流后计量层日志: [INFO] cross_zone overflow=deptA mode=soft_limit priority=high [INFO] failover executed from=az-a to=az-b cost=4.8s version=v37