本文是公开报告的摘要与解读,事实以原始报告为准。
2021 年 1 月 4 日是新年第一个工作日。Slack 当天发生大面积可用性事件:消息发送失败或变慢,随后整体不可用,恢复后仍有一段时间处于降级状态。Slack 工程博客于 2021 年 2 月 1 日发布复盘,作者为 Senior Staff Engineer Laura Nolan,2 月 3 日更新。
报告给出的根因不是当天发布:一个 AWS Transit Gateway(TGW)在每包速率突增时没有及时扩容,开始丢包;当天发布过的变更被回滚并排除。另一个独立问题是监控:Dashboard 和告警服务与它们的数据库位于不同 VPC,同样依赖 TGW,因此在事故中一起失效。报告没有给出精确的受影响用户数,也没有给出一个正式的“总故障时长”数字;按报告时间线,服务在 7:00 左右不可用,10:40 恢复正常。
以下时间均为 1 月 4 日 PST。
| 时间 | 事件 |
|---|---|
| 亚太白天、欧洲上午 | 服务正常 |
| 美洲上午 | 外部监控因错误率上升呼叫值班;随后 Dashboard 和告警失效,监控团队被呼叫 |
| 6:57 | 99% 的消息仍能成功发送,正常水平是高于 99.999%;网络已出现异常 |
| 7:00 | 整点/半点的定时流量高峰叠加网络降级,Web 层被打满,丢包和后端延迟上升,Slack 不可用 |
| 7:01–7:15 | 尝试扩容 1,200 台 Web 服务器,provision-service 失败 |
| 约 8:15 | provision-service 恢复,健康实例开始进入服务 |
| 约 9:15 | 可用主机足够,服务从“完全不可用”转为“降级” |
| 10:40 | AWS 手动提升 TGW 容量并覆盖所有可用区,网络、错误率和延迟恢复正常 |
报告描述的用户体验是消息发送失败或变慢,Slack 不可用,之后一段时间仍降级。Slack 官方状态页把登录/SSO、连接、消息、文件、通知、Huddles、搜索、应用/集成/API、工作区管理列为受影响范围;核心访问在 10:40 左右恢复,日历集成、邮件通知和桌面客户端的一个独立问题在此后继续处理。
事故还直接影响了响应者:自动缩容移除了生产实例,许多工程师的 SSH 会话被中断;监控系统自身不可用,团队在“看不见”的状态下排障。报告没有提到数据丢失或数据损坏。
第一层是网络。一个 AWS TGW 被打满并丢包。TGW 由 AWS 管理,设计目标是透明扩容,但这个 TGW 没有跟上每包速率的突增。报告给出的背景是:假期后第一个周一,客户端缓存为空,重新连接需要下载更多数据,流量从低活跃状态突然上升。AWS 手动增加了 TGW 容量,并表示正在审视 TGW 对大规模每包速率增长的扩容算法。
第二层是自动扩缩容。Web 层按 CPU 和 Apache worker 线程利用率扩缩。网络等待降低了 CPU,触发了最初的缩容;缩容移除实例,也移除了工程师的 SSH 会话。之后线程压力上升,触发一次 1,200 台服务器的大规模扩容。这个方向本身没有错,但扩容执行失败。
第三层是 provision-service 的瓶颈。它负责配置和测试新实例,同样依赖降级的网络。1,200 台的突发请求撞上两个资源上限:Linux 打开文件数限制(报告称这是更大的问题)和一项 AWS 配额。大量实例只完成部分配置,无法提供服务;这些坏实例又撞上自动扩缩组的上限。provision-service 过载还导致新的 Dashboard 主机无法创建。报告明确排除了当天部署:相关变更被回滚并排除。
团队先把它当作网络问题升级给 AWS,同时尝试扩容。发现缩容在破坏实例和 SSH 会话后,团队关闭了缩容。7:01–7:15 的 1,200 台扩容失败后,重点转向恢复 provision-service;约 8:15 它恢复工作,健康实例开始进入服务。报告说还需要约一小时才能配置出足够实例,把错误率压到较低水平。
在实例不足期间,负载均衡器的“panic mode”、重试和熔断机制帮助恢复了部分服务,尽管健康检查大量失败。由于网络仍在降级,团队需要比平时更多的实例,配置也更慢。10:40 AWS 的 TGW 扩容覆盖所有可用区后,网络、错误率和延迟才恢复正常。
后续改进包括:把 Dashboard 实例迁到与其数据库相同的 VPC;定期对 provision-service 做负载测试;重新评估健康检查和自动扩缩策略,避免扩容本身压垮 provision-service;在下一次假期结束时提前请求 TGW 扩容,并为此设置了提醒。AWS 则表示正在审视 TGW 的扩容算法。
第一,托管服务的“透明扩容”不等于无限容量。TGW、NAT、负载均衡器和云配额都有每包速率、连接数或 API 上限,关键依赖要知道上限、监控水位和升级路径。
第二,监控必须与被监控系统解耦。Dashboard 和告警放在不同 VPC,却依赖同一个 TGW,导致事故中“监控和告警一起下线”;监控应跨可用区、跨账号或走独立路径。
第三,自动扩缩容要考虑供给链。只盯着服务实例的 CPU 和线程不够,还要确认 provision-service、镜像仓库、配额和 OS 限制能承受扩容峰值;否则扩容会变成自我 DoS。
第四,缩容在事故中可能是危险动作。它会移除实例、切断调试会话,甚至删掉正在提供服务的容量;事故期间应关闭缩容或设置容量下限。
第五,健康检查和实例替换要避免“大规模同时发生”。不健康的实例被集中替换,会进一步压垮配置系统;需要速率限制和退避。
第六,日历效应要进入容量计划。节后第一个工作日、整点定时任务、客户端冷缓存,都是可以提前预演的流量模式。
合上页面,先回答,再展开对照。
小程序版
微信扫码,随时查命令