---
author: Peter Pang
date: '2025-10-31'
guest: ''
layout: post.njk
source: https://www.youtube.com/watch?v=ITw5hZWeAyE
speaker: Peter Pang
tags:
  - cloud-computing
  - system-failure-analysis
  - software-architecture
  - risk-management
  - devops-practices
title: 互联网史上最长宕机：AWS DynamoDB 故障深度解析
summary: 本文深度解析了AWS于2025年10月19日发生的、长达14小时32分钟的史上最长云服务瘫痪事件。故障起因于DynamoDB的一个低级Race Condition代码错误，但其广泛影响源于AWS复杂的微服务架构、重试机制缺陷以及企业在成本与容错之间的商业权衡，最终导致了区域性故障演变为大范围服务中断。文章探讨了从技术根源到商业决策的各层级原因，并反思了技术服务于现实世界的本质。
insight: ''
draft: true
series: ''
category: software-development
area: tech-engineering
project: []
people: []
companies_orgs:
  - AWS
  - Google
  - Microsoft
  - Azure
products_models:
  - DynamoDB
  - EC2
  - DWFM
  - Network Manager
  - NLB
  - DNS
  - Route53
  - ECS
  - EKS
  - IAM
  - CDN
  - DDoS
media_books:
  - 让编程再次伟大#40
  - 让编程再次伟大#7
status: evergreen
---
### 宕机肇始与连锁反应

2025年10月19日晚上11:48，正准备休息的AWS员工迎来了一则噩耗：核心数据库产品 **DynamoDB** 出现了连接故障。这一故障直接导致依赖它的上百个云服务产品随之下线。最初的故障源自一个被形容为“教科书式”的 **Race Condition**（竞态条件），即两个修改数据的命令前后冲突，最终导致了数据库连接问题。

尽管工程师们在3个小时内迅速修复了 **DynamoDB** 的 **Race Condition** 漏洞，但灾难并未就此结束。作为 **AWS** 最引以为豪的产品之一，**DynamoDB** 几乎是所有内部系统的默认数据库。因此，在这3个小时的宕机期间，大量系统累积了无数需要重试的任务。其中就包括负责调度所有 **EC2** 服务器资源的内部管理程序——**Droplet WorkFlow Manager（DWFM）**。

2025年10月20日凌晨2:25，在 **DynamoDB** 恢复的那一瞬间，**DWFM** 被堆积如山的待办事项瞬间冲垮，导致调度中心宕机，进而引发所有 **EC2** 服务器无法启动。这再次凸显了重试机制设计上的缺陷。更令人担忧的是，如此重要的程序竟然没有自动恢复机制；赶来修复的工程师甚至没有一份可以参考的手动恢复流程，这表明 **AWS** 内部在此之前从未认真考虑过“如果 **DWFM** 挂了该怎么办”的极端场景。

直到凌晨5:28，**DWFM** 才得以恢复，**EC2** 服务器也开始正常启动。然而，旁边的 **Network Manager**（网络管理器），一个负责掌控所有 **EC2** 网络功能的程序，此刻却累积了长达6个小时的待办事项。加上刚大量重启的 **EC2** 发出的海量新请求，其处理速度已不足以应对新增任务，工程师们只能再次手动 SSH 进去进行疏导。直到早上10:36，积压的待办事项才处理完毕，**EC2** 的网络功能才恢复正常。

几乎在同一时间，负责分配网络流量的负载均衡器 **NLB**（Network Load Balancer）也开始为重启的 **EC2** 服务器引流。但由于 **Network Manager** 的卡顿，部分 **EC2** 服务器时而可联系，时而无法联系，导致 **NLB** 的健康检查在红灯和绿灯间反复横跳，并引发 **DNS** 的反复下架和上架。忍无可忍的工程师们在9:36被迫关闭了 **NLB** 的健康检查，使其忽略无响应服务器，暂时维持绿色状态。直到下午2:09，所有积压的 **EC2** 服务器才恢复正常，**NLB** 的健康检查重启，网络功能才最终全面恢复。2:20，最后一批受影响的容器服务 **ECS** 和 **EKS** 也恢复正常，此次长达14小时32分钟的瘫痪事故宣告结束，成为有记录以来云服务行业历时最长的一次大规模宕机。

### Race Condition 根源剖析

与早期Google Cloud的瘫痪事故相比，**AWS** 本次事故的“草台”程度相对较低。除了最开始的导火索，大部分问题源于错综复杂的架构导致的连锁反应以及系统体量过大产生的极端高负荷压力。巧合的是，这两次瘫痪事故的导火索都是入门级的代码错误。

本次 **AWS** 事故的源头，是 **DynamoDB** 系统中负责处理 **DNS** 的两个程序：负责生成 **DNS** 记录的 **planner** 和负责将新记录写入 **DNS** 系统的 **enactor**。为了保证容错，**DynamoDB** 在三个可用区部署了三个独立的 **enactor**。每当 **planner** 生成一个新记录，其中一个 **enactor** 就会获取并尝试写入 **DNS**。在写入前，**enactor** 会进行一个前期检查，确保它手上的记录比当前 **DNS** 中的更新；写入成功后，还会执行一个清理动作，抹掉 **DNS** 中比其刚写入记录更早的那些记录。

在10月19日晚上，出现了一个极端情况：**enactor** 张三首先从 **planner** 拿到记录A，在写入 **DNS** 时遇到了延迟，暂时停滞。此时，**planner** 又生成了记录B。**enactor** 李四拿到记录B并顺利写入 **DNS**。就在李四准备执行清理动作时，张三的延迟结束，继续执行任务，将记录A写入 **DNS**，覆盖了记录B。随后，李四开始清理，发现 **DNS** 中比它刚写入的记录B更早的记录是A，于是按照代码逻辑将记录A抹掉。当张三和李四都完成任务后，指向 **DynamoDB** 域名的 **DNS** 记录变得为空。此时，**planner** 生成了新记录C，**enactor** 王五拿到记录C准备写入，却在前期检查阶段被卡住——因为 **DNS** 中没有记录，无法与记录C进行对比。逻辑因此进入死胡同，无论 **planner** 后续生成多少新记录，都没有 **enactor** 能成功写入 **DNS**。**DynamoDB** 的域名从互联网上彻底消失，导致其下属产品也随之瘫痪。这个错误，相较于Google Cloud忘记写 `try catch` 导致 `NullPointerException`，仅是“好一点点”。

演讲者提出，**DynamoDB** 的这个 **Race Condition** 问题，其根源在于架构设计。在“多个进程修改同一个数据”的场景下，不应将“保证数据完整性”的任务放在进程本身，而应由数据的接收和储存方承担，即 **DNS** 系统 **Route53**，作为 **single point of truth**。让每个 **enactor** 都进行事前事后检查和清理，无论代码多严谨，都是不合理的决定，因为 **ACID**（原子性、一致性、隔离性、持久性）本来就极难完美达成。

### 成本、风险与纳什均衡

与 **AWS** 形成鲜明对比的是，微软的云服务 **Azure** 在制作本期视频时，也正经历全球范围的宕机，这已是 **Azure** 当年的第五次世界级故障。然而 **Azure** 的新闻曝光度远低于 **AWS**，部分原因在于其大客户多为传统行业巨头，普通民众感知不深。但仔细分析其故障报告，会发现 **Azure** 的问题多集中在 **CDN**（内容分发网络）运维失误、**DDoS**（分布式拒绝服务攻击）或两者结合，很少出现拖垮整个体系的严重连锁反应。

**AWS** 的风格则截然不同，正如早期视频提到的，**AWS** 崇尚微服务架构，倾向于使用现成服务而非自建轮子。久而久之，服务间的高度耦合使得“牵一发而动全身”。本次事故中，**DynamoDB** 拖垮 **DWFM**，**DWFM** 拖垮 **EC2**，**EC2** 拖垮 **NLB** 的连锁反应，完美体现了 **AWS** 内部系统“同生共死”的状态。回顾 **AWS** 历史上的大规模瘫痪事故，导火索多是 **DynamoDB**、**S3**、**Lambda** 等通用存储和计算服务，这些服务是绝大多数 **AWS** 产品的基础，因此被微服务架构的原则紧密串联。

一个敏锐的观察是，包括本次事故在内，**AWS** 的重大故障似乎总发生在“**us-east-1**”分区。这引出了一个核心疑问：云服务主打的分布式部署、高容错和稳定性，为何一个分区出故障就能拖垮半个互联网？虽然云服务在市场营销中常与分布式、高容错挂钩，但这仅仅是提供了搭建高容错系统架构的环境，实际是否搭建取决于用户。即使是 **AWS** 自己，也未能完全遵循此原则，例如其管理权限系统 **IAM**（身份与访问管理），只在 **us-east-1** 分区设有写入节点，其余分区仅为只读节点。

而对于大多数企业而言，最关键的问题是：是否愿意投入额外成本进行多点部署？这本质上是一个商业问题。技术上，**multi-node**（多节点）、**multi-region**（多区域）、**multi-cloud**（多云）等容错方案已相当成熟，多数云服务商均提供开箱即用的服务。然而，“钱”是关键症结：两个节点意味着两倍成本，两个区域四倍，两个云八倍。如果CEO面前有一个按钮，按下可避免几年一次、持续数小时的全面瘫痪，但代价是成本翻八倍，多数CEO可能不会按下。

这其实是一个博弈论问题。对企业而言，最怕的不是自家产品出问题，而是“只有自家产品出问题”。若集体出问题，媒体会归咎于云服务商，企业仅是受害者。这种几年一次的事故，对大众而言已属 **black swan event**（黑天鹅事件）。即使投入巨额成本做好容错，逃过一劫，也不会因此获得表扬，例如此次事故中毫发无损的 **Netflix**，作为 **AWS** 最大客户、模范生，其表现也“nobody cares”（无人关注）。

因此，从CEO视角看，更关心用户和股民的反应，最优解就是采取与其他企业相同的做法。**AWS** 最早成立、功能最快、资源最丰富的 **us-east-1** 分区，吸引了早期企业集中部署，后来者也自然将其视为首选乃至唯一选择。结果是所有人都在 **us-east-1** 上“抱团，同生共死”，形成了一个完美的 **Nash equilibrium**（纳什均衡）。

尽管作为程序员，看到技术被如此“糟蹋”会感到气愤，但从宏观上看，无论是 **AWS** 内部产品间的互相捆绑，还是用户扎堆在单一分区部署，这些决定可能不是最科学的，但无疑是最现实的。技术人追求完美，但世界并非围绕技术运转，技术只是服务于世界的工具。归根到底，我们都只是工具人。