W43-从 AWS 事故学习到的教训

上周 AWS 出现持续 15 小时的重大故障,全球超过 1000 家企业服务中断,造成数十亿美元经济损失。学习到一个深刻的教训:再精妙的工程设计,也敌不过一个单点依赖。

这次事故发生在 AWS 最关键的 us-east-1 区域。根因是 DynamoDB 的 DNS 管理自动化出现竞态缺陷,误清空了区域端点的 IP 记录,导致解析失败。us-east-1 并不是一个普通的数据中心,它是 AWS 全球基础设施的“中枢神经系统”,几乎所有区域的公共控制平面都依赖于此,包括 EC2 调度、NLB、Lambda 等关键服务,因此引发了级联崩溃。

更讽刺的是,事故发生 75 分钟后,AWS 状态页仍显示 “一切正常”——因为 CloudWatch 本身也依赖 DynamoDB,监控系统跟着失明。

恢复过程也并不轻松。DNS 记录虽能快速修复,但 DynamoDB 是核心控制节点,EC2 调度器需要为数万台服务器重建租约,网络管理器要清理拥塞并分发延迟状态,负载均衡器因误判实例健康状况反复将其剔除。最终 AWS 只能关闭自动健康检查与故障转移,人工干预才让系统避免不断雪崩。

看完热闹后,回顾一下我们自己的服务。最可能埋下系统性单点隐患的,反而是业务迭代关注度不高的基础服务。例如信息化入口、验证类服务,其中信息化入口业务逻辑简单,但爆破面巨大,掌握着 80% 的流量。这类服务的工程设计,应遵循最小依赖、最大熵原则,保持极致的清晰与简单。

信息化入口这种小组件,对有野心的工程师有一定诱惑性,因为有突出工程挑战:维护面向多个技术栈的多版本,发版周期长依赖业务宿主页面。回看今年我们在信息化入口做的事情,我觉得有必要复盘一下是不是选择了一个正确的方向。为了实现动态更新,缩短业务迭代的发布周期,提升发布灵活性。在工程上做了很多工作,引入了更多的依赖、设计了更复杂的架构,同时也降低了回滚生效效率。按照这个方向,动态化解决完了可能下一步就要搞一个动态组件跑在各个容器里,收敛信息化入口的实现版本,做到高动态高复用。只是当信息化入口过了迭代高峰后, feature 就有了债务的影子。

我反思今年的注意力还是在训练工程能力上,给大家创造些锻炼花拳绣腿的机会,没有足够左移到提升技术决策质量上。在决策时缺乏清晰的框架、事实依据和逻辑推演。唯一做对的一件事,我认为是引入了民主、集体决策。

每个工程师的成长过程都会经历这样的认知习惯,厌恶冗余、抽象一切、强调复杂,以此判断技术含量。要勇于抛弃这些中段水平的认知,追求经过权衡后的清晰与简单,就像 Unix 设计哲学,要品味高级货。

最后更新于