高可用系统的工程实践复盘:从“设计正确”到“长期可用”

10 阅读5分钟

在云通信行业里,高可用从来不是一个“架构图问题”,而是一个长期的工程问题。很多系统在设计阶段看起来已经满足“多活、冗余、自动切换”,但一旦进入真实生产环境,就会暴露出各种细节问题:抖动、误判、雪崩、恢复慢。

这篇复盘不讲概念,重点拆解在实际项目中踩过的坑,以及最终沉淀下来的工程方法论。


一、目标澄清:高可用不是99.99%,而是“业务可持续”

很多团队在一开始就把目标设定为:

  • 99.9% / 99.99% 可用性
  • SLA达标

但在通信系统中,这种指标往往不够具体。

更有效的目标应该是:

  • 核心链路不中断(如验证码、通知)
  • 局部故障不扩散
  • 系统在异常情况下仍然“可控”

换句话说,高可用的本质不是“不出故障”,而是:

出问题时,系统仍然能以“降级状态”持续提供服务。


二、第一次失败:我们低估了“局部故障”的破坏力

早期架构中,我们已经做了这些:

  • 多通道接入(多个短信供应商)
  • 负载均衡分发
  • 基础重试机制

按理说,已经具备一定的高可用能力。

但在一次真实事故中:

  • 某一个国家的某个运营商通道异常(延迟暴涨)
  • 系统没有及时识别
  • 请求持续打到该通道
  • 重试机制反而放大流量
  • 最终导致整体发送成功率下降

问题的核心不是“没有备份通道”,而是:

👉 没有做到“快速隔离故障”。


三、关键转折:从“冗余”到“隔离”

很多人理解高可用 = 冗余(多机房、多通道、多实例)

但在工程实践中,更关键的是:

隔离(Isolation)比冗余更重要

我们做的第一个关键改造:

1. 故障隔离粒度细化

从原来的:

  • 通道级别

升级为:

  • 国家级
  • 运营商级
  • 通道级
  • 路由策略级

一旦某一维度异常,可以快速“摘除”。


2. 引入熔断机制(Circuit Breaker)

当检测到:

  • 延迟超过阈值
  • 成功率低于阈值

系统自动:

  • 停止向该通道发送
  • 切换到备选路径

这一步直接解决了“故障放大”的问题。


3. 重试机制重构

原来的重试逻辑:

  • 简单重发(同通道)

优化后:

  • 跨通道重试
  • 指数退避
  • 带策略的重试(成本 / 成功率)

四、第二个坑:监控很多,但没有“决策能力”

我们曾经有非常完善的监控:

  • 成功率
  • 延迟
  • 吞吐量
  • 错误码

但问题是:

👉 监控 ≠ 可用性保障

原因在于:

  • 数据是事后统计
  • 缺乏实时决策能力
  • 人工介入太慢

改进方向:从“可观测”到“可调度”

我们做了三件关键事情:

1. 实时指标流

  • 从分钟级 → 秒级
  • 支持快速判断通道状态

2. 路由决策引擎

基于实时数据,动态选择:

  • 最优通道
  • 备选路径

不再依赖人工配置。


3. 自动化策略

例如:

  • 成功率 < 90% → 自动降权
  • 延迟 > 2s → 切换通道

👉 这一步本质上让系统具备了“自愈能力”。


五、第三个坑:多活架构 ≠ 真正高可用

我们曾上线过“多活架构”:

  • 多区域部署
  • 流量分发

但在一次故障中发现:

  • 一个区域异常
  • 流量切换成功
  • 但下游依赖(如数据库、缓存)未完全隔离
  • 导致问题扩散

核心教训:

多活如果没有“依赖隔离”,只是放大复杂度


改进措施:

1. 依赖分层隔离

  • 通信调度层(可多活)
  • 状态存储层(分区隔离)
  • 日志与分析层(异步处理)

2. 跨区域降级策略

例如:

  • A区异常 → B区接管
  • 若B区压力过大 → 限流 + 降级

3. 明确“放弃策略”

不是所有请求都必须成功:

  • 验证码:必须优先保障
  • 营销消息:可延迟或丢弃

👉 高可用的本质之一:资源优先级管理


六、工程层面的几个关键原则

基于多次实践,总结出几个“真正有用”的原则:


1. 不要相信“平均值”

平均成功率 99% ≠ 每个国家都是99%

必须关注:

  • 长尾问题
  • 局部异常

2. 所有自动化都要“可回滚”

  • 自动切换
  • 自动降级

一旦策略错误,必须能快速回退。


3. 设计“失败路径”

不要只设计成功流程:

  • 如果发送失败怎么办?
  • 如果所有通道都失败怎么办?

4. 系统要“抗抖动”,而不是“过度敏感”

过于敏感会导致:

  • 频繁切换通道
  • 系统震荡

需要:

  • 阈值 + 时间窗口
  • 抑制抖动机制

七、最终演进:从系统到“稳定性工程体系”

当系统复杂度提升后,高可用不再是某个模块的能力,而是一个体系:

包括:

  • 架构设计(多活 / 隔离)
  • 调度系统(动态路由)
  • 监控系统(实时指标)
  • 自动化系统(自愈能力)
  • 运维体系(应急响应)

结语

很多团队在做高可用时,会陷入一个误区:

以为“设计好了架构”,就等于“系统稳定了”

但真实世界是:

  • 故障一定会发生
  • 关键在于是否可控
  • 是否能快速恢复
  • 是否影响核心业务

如果用一句话总结这次工程复盘:

高可用不是架构能力,而是持续演进的工程能力。

在云通信这种对实时性和成功率高度敏感的场景中,这一点尤为明显。