GitHub 8·17 大故障复盘:7 小时 47 分钟的容量失败与重试风暴教训
原创 · 约 25 分钟阅读 · 阅读 --

GitHub 8·17 大故障复盘:7 小时 47 分钟的容量失败与重试风暴教训

作者: Alex Xiang


我是 Alex Xiang,字与码(zicode.com)主理人。7 小时 47 分钟的全球中断,根因却出在一个「被监控漏掉的 sidecar」。这篇把官方复盘与社区讨论拆开,并提炼成任何规模系统都能用的工程清单。欢迎关注公众号「字与码」。

2026 年 8 月 20 日,GitHub 官方博客发布了对 8 月 17 日大故障的复盘:那次事故持续 7 小时 47 分钟,波及 github.com、身份认证、Actions、API、Pull Request、Issues 与 Copilot。这是 8 月内第二次重大事件(此前 8 月 6 日已发生过一次 Actions 故障)。官方给出的根因不是代码或配置变更,而是「容量失败」:流量到达新峰值时,美国中部数据中心某个关键基础设施组件没能随之扩展,容量压力扩散,引发认证失败并连带多个服务中断。复盘发布当天冲上 Hacker News 首页(327 分、373 条评论),社区反应激烈。

这篇文章还原官方复盘的时间线与数据,拆解「容量失败 + 重试风暴」这两个工程教训,再结合社区讨论给出可迁移到任何规模系统的建议。与多数二手解读不同,这里补上了官方根因里最关键的那个细节——出问题的不是主服务,而是它身旁那个没人盯的 sidecar

一句话先给结论:GitHub 把 8 月的两次事故定性为「增长没有跟上规模」:4 个月内月提交量从 14 亿翻倍到 29 亿,关键组件容量触顶;恢复期 Copilot 服务的报错又触发了客户端无限重试,形成二次风暴。精确根因是 Istio sidecar 达到并发上限、而扩容策略只看主服务容量,没能及时给它加实例;4 个 HAProxy 节点流限制耗尽拖垮网关认证。官方对策是加容量(300 万核 CPU、120PB 存储)、继续迁往 Azure(平台负载占比从 5 月的 12% 升至 58%),并给服务间调用统一加上重试预算与可变超时。

一、事故还原:8 月 17 日发生了什么

按官方博客与后续多家媒体对根因的还原,关键事实如下:

  • 时间窗:8 月 17 日 13:28 UTC 起,至 21:15 UTC,共 7 小时 47 分钟
  • 峰值错误率:web/API 约 20%,archive 与 raw-content 下载高达约 50%
  • 受影响面:github.com、SAML/OIDC 身份认证、SCIM、Team Sync、GitHub Actions(含依赖 GitHub.com 公共 workflow 定义的 GHEC Data Residency)、API、Pull Request、Issues 以及 Copilot;
  • 直接根因:美国中部数据中心(Central US)流量创新高,部分 Istio sidecar pod 达到并发上限,而其自动扩容策略监控的是主服务的容量、不是 sidecar 自身,于是没有及时加实例;压力扩散后,4 个 HAProxy 节点耗尽流限制(flow limit),网关认证链路出现大面积延迟与失败;
  • 恢复过程:团队把流量从 Central US 切到 Northern Virginia、暂停异常 HAProxy 节点,主服务当天早些时候恢复;但 Copilot 恢复更慢;
  • 恢复期的坑:Copilot 服务中的报错触发了客户端侧重试循环,在恢复期间进一步抬高流量,团队必须先压制该行为,才能安全恢复流量;
  • 额外干扰:故障期间针对 codeload 接口的多起爬取攻击叠加,进一步拖慢恢复;
  • 定性:8 月 6 日与 8 月 17 日两次事故均非代码或配置变更引发,核心都是容量失败——「我们没能在需求超过容量之前扩展关键组件」。

二、恢复时间线(精确到组件)

时刻(UTC)事件
13:28Central US 网络饱和,错误率开始攀升
~16:36多数服务随 Central US 恢复而恢复(约故障后 3 小时)
~18:03Actions 持续降级至此才恢复
21:02Copilot Token Service 完全恢复(最晚)

注意「多数服务 16:36 恢复」容易让人误以为事故结束了——真正的全局恢复要到 21:15。Copilot Token Service 成为最短板的那块木板,整整多拖了 4 个多小时。

三、数据:增长有多猛

指标数值说明
月提交量(4 月)14 亿4 个月基线
月提交量(8 月)29 亿翻倍以上
新增 CPU 核心300 万+容量补充的一部分
新增高速存储120 PB容量补充的一部分
Azure 承载平台负载约 58%(5 月为 12%)一半以上 Git 操作已迁移到 Azure

GitHub 的原话是:「这种增长解释了系统的压力,但并不能为故障开脱(explains the pressure on our systems, but it does not excuse these outages)」。把负载翻倍和「Copilot 带来的 AI 生码 → 更多 commits/PR」联系在一起,是这次增长最合理的解释——而它恰恰是最难用「经验预留」来对抗的那类增长。

四、教训一:容量扩展是「增长函数」而不是「计划任务」

这次复盘的第一个核心教训:容量规划要按负载增速动态执行。月提交量 4 个月翻倍意味着峰值形态也在快速变化,静态预留或滞后扩容的组件会在流量突增时第一个触顶。官方列出的对策是三条线并行:

  • 加容量:在既有数据中心电力允许的范围内尽可能加装硬件,同时加速向 Azure 迁移(58% 平台负载、一半 Git 操作已在 Azure);
  • 提效率:更高效的资源利用,降低单位负载对容量的需求;
  • 拆瓶颈:消除架构上的串行依赖——下一个里程碑是「读容量随读者数量线性扩展」的架构,先从小型/大型 monorepo 逐步灰度,目标是支撑无限读操作。

最该被记住的,是那个被漏掉的 sidecar:扩容策略盯错了对象。主服务还有余量,但它身旁的 Istio sidecar 已经触顶——监控系统报「主服务健康」,可真正先垮的是没人单独盯的代理。对普通团队的迁移价值:把「容量上限」画成一条线,把「负载」画成另一条线,两条线的交叉点就是事故触发点;并且,凡是「主服务 + 旁路组件」的架构,旁路组件的容量必须被纳入同一套扩容判据,否则它就是下一个隐蔽瓶颈。

五、教训二:重试风暴是恢复期的隐形杀手

这次复盘里最值得技术人细读的细节是:服务恢复阶段,Copilot 报错触发了客户端侧重试循环,抬高了恢复期流量,团队必须先处理它才能安全恢复流量。这是典型的「雪崩恢复失败」模式:

服务报错(5xx / 超时)
    → 客户端立即重试(无退避 / 无预算)
      → 瞬时流量放大 N 倍
        → 正在恢复的服务再次被打满
          → 恢复被推迟 / 雪崩扩散

官方为此落地的两个即时变更,值得直接抄进任何微服务体系:

  • 统一重试预算与重试上限:服务间调用(service-to-service)采用一致的重试限制(retry limits)、重试预算(retry budgets)与可变超时(variable timeouts),防止重试风暴与级联负载;
  • 重审低优先级 CPU/内存告警:识别「平时不告警、流量突增时最先扛不住」的组件,提前加固。

注意「可变超时」这个点:固定超时在高峰时会导致大量请求同时超时、同时重试,形成同步震荡;可变/抖动超时(jittered timeout)能让重试错峰。

这次最精彩的对照是:两套互不相干的代码、两套不同的重试机制,在同一天演出同一个失败模式——先是网关侧乐观重试压垮内部 LB,后是 VS Code 里一个潜在 Bug 把 Copilot Token 流量放大约 10 倍(正常 7–9K RPS → 事故期 70–100K RPS)。「暂停异常 HAProxy + 阻断触发重试的响应」对两次都奏效。这说明重试风暴不是某个 Bug,而是分布式系统的通用 hazard。

六、官方承诺与社区反应

官方表示已把更多团队和资源转向可用性,投资更强的测试、更安全的发布(safer rollouts)、更好的可观测性与告警,并隔离关键系统、消除共享依赖(removing shared dependencies),以「降低故障概率、限制故障影响」。GitHub CTO Vlad Fedorov 的署名文章态度克制:「8 月 17 日,你没法依靠我们。这是我们的责任去修复它——我们会通过平台的扩展性与可靠性赢回信任。」

但 HN 社区(373 条评论)并不买账,争论集中在三处:

  • 道歉缺失:全文没有出现 "sorry" 或 "apologize","If you were trying to ship software that day, we let you down" 被批为「经典的公司式非道歉话术」;
  • Azure 的既当运动员又当裁判问题:有评论直言「把 Azure 当作解决方案,而它恰恰是大部分问题的来源」;
  • 补偿缺位:付费用户质问——Actions 分钟数被故障烧掉,官方是否该退款;以及对「连续两次大事故」后平台稳定性的信任问题。

也有理性的声音:「评论区的大家被惯坏了。大部分用户免费使用 GitHub,却还抱怨。这次故障源于巨大的负载增长——4 个月 commits 翻倍到 29 亿,任何做过高负载系统的人都知道这不是正常增长。」

七、独立观点:把瓶颈画在「组件级」,而不是「服务级」

我读完复盘最大的收获,不是「要加容量」(这是废话),而是「容量监控的粒度必须细到瓶颈组件本身」。GitHub 的监控大概率在报告「主服务健康」,可压垮系统的却是 sidecar 的并发上限——一个健康的聚合指标,掩盖了一个先死的具体组件。这给我们两个可操作的提醒:

  • 给每条关键路径画「子容量曲线」:网关、sidecar、连接池、线程池、流限制——这些才是真正先触顶的地方,要把它们的余量当作一级指标,而不是只在「服务 up/down」层面看;
  • 重试预算必须是全局契约:客户端(VS Code)、网关、服务间,三者的重试上限要一致且可观测,否则恢复期任何一端「好心重试」都会把系统重新打满。注意客户端侧同样关键——你控制不了用户的 VS Code,但可以在服务端对「单位客户端的请求速率」做熔断与限流。

更大图景上,GitHub 在走的方向(读容量线性扩展、去共享依赖、向 cell/区域化架构靠拢)与业界共识一致:cell-based architecture(如 AWS 的 cell)、static stability(即使区域故障也不依赖跨区域调用)、load shedding(主动丢弃低优先级流量)、bulkhead(舱壁隔离)。这些不是新词,但每一次大厂故障都在重申它们的重要性。值得一提的是,GitHub 这次「切到 Northern Virginia 反而被重试打爆」也说明:故障转移本身会制造流量突刺,转移后要配合客户端退避与服务端限流,否则只是把火引到另一堆柴上

八、给工程团队的迁移清单

  • 重试要有预算:给每个服务调用配「重试次数上限 + 重试预算 + 抖动退避」,预算耗尽就快速失败(fail fast),而不是无限重试;
  • 超时用可变值:固定超时 + 高并发 = 同步重试风暴;引入 jitter 让重试错峰;
  • 把容量画成组件级曲线:持续监测「主服务 vs sidecar/连接池/流限制」的逼近程度,容量增长做成自动化而非手工排期;
  • 恢复要「先止血再放量」:故障恢复时先压制客户端重试(熔断/降级/服务端限流),等系统稳定再逐步放开流量;
  • 审计「低优先级告警」:平时不响的 CPU/内存/并发告警,往往是流量突增时最先崩的组件;
  • 故障转移要配套退避:切区域/切节点会产生流量突刺,转移后必须限制入口速率,避免「转移即二次打满」。
GitHub 复盘的潜台词是规模化的残酷现实:当月提交量以「翻倍」为单位增长时,「按经验预留容量」的运维模式必然失效,只有把容量、重试与超时都变成系统性的可量化机制,才能扛住下一波峰值。对任何正在高速增长的公司,8·17 都是一份免费的预警报告——而且代价是 GitHub 替你付的。

结语

GitHub 8·17 故障是「增长型故障」的典型案例:不是改坏了什么,而是没来得及长大。它留给行业的两个最可操作的资产是——重试预算与可变超时的工程规范,以及「读容量线性扩展」的架构方向。至于信任,正如评论区所说,只能靠接下来的稳定表现慢慢赢回。而对每一个构建分布式系统的团队,最该带走的一句是:盯住那个没人盯的 sidecar。

信息来源

  • GitHub 官方博客:The August 17 outage, and the work ahead(Vlad Fedorov,GitHub CTO,2026-08-20)
  • 根因细节还原:StatusCake、ITPro、cnBeta、IT168 等对 Istio sidecar 并发上限、HAProxy 流限制、VS Code 重试 Bug(Copilot Token 70–100K RPS)、codeload 爬取攻击的报道
  • Hacker News 讨论:The August 17 outage, and the work ahead(327 分 / 373 条评论)
  • 背景:GitHub 可用性报告(2026 年 7 月、6 月,GitHub Blog);8 月 6 日 Actions 故障
打开原图 ↗