
10 月 22 日星期一某海外云服务商发生了一次服务故障。由于该故障导致多个热门网站宕机数小时事件引发了广泛关注。某海外流媒体服务提供方也受到了一定影响但对终端用户造成的实际影响较小。从高可用架构、故障隔离和可用区疏散的角度来看这次事件具有较强的参考价值。回顾此次事件我们有一些应对措施做得比较到位也有一些地方本可以做得更好。本文将从我们的视角梳理此次云服务性能下降事件的时间线并分享我们在降低用户影响、提升系统韧性方面采用的一些实践方法。事件时间线从性能下降到可用区疏散周一上午 8:30 刚过我们注意到几个托管在某海外云服务商平台上的大型网站开始出现问题并陆续返回错误。随后我们检查了自身的监控系统发现我们的服务尚未受到影响。上午 10:40该云服务商更新了状态页显示其块存储服务出现性能下降。由于我们一直重视服务在单个实例故障下的容错能力并且尽量避免依赖块存储服务进行持久化数据存储因此当时我们的服务仍然保持正常。大约上午 11 点部分用户开始遇到间歇性问题。由于我们的大多数客户端软件都针对间歇性服务端故障进行了韧性设计因此绝大多数用户并未察觉异常。上午 11:15问题开始变得更加严重我们随即触发内部告警并开始排查原因。当时问题表现得更像是网络故障而不是块存储系统故障这在初期造成了一定混淆。事后来看我们本应更早触发告警。这样一来我们就能更快缩小问题范围并更早采取修复措施。在将网络问题定位到单个可用区之后该云服务商也确认网络性能下降仅限于该可用区。得知影响范围只局限在一个可用区后我们立即开始将用户流量从受影响的可用区疏散出去。由于此前曾经历过单可用区故障我们会定期开展可用区疏散演练。基于这些演练经验以及我们从以往故障中吸取的教训我们毫不犹豫地决定疏散故障可用区。我们预期此次疏散会像以往演练一样迅速而顺利因此立即采取了行动。过去的经验表明可用区疏散是应对单个可用区局部故障的有效方法。因此我们在内部云管理平台中对这一流程进行了工具化支持只需点击几下鼠标即可完成可用区疏散。此次事件中这项准备发挥了重要作用我们仅用 20 分钟就完成了故障可用区的疏散并为所有用户全面恢复了服务。如何构建高可用系统结合过去的故障经验以及我们从一开始就坚持的韧性设计理念我们总结出了一些构建高可用系统的实践模式。这些实践不仅适用于云服务故障应对也适用于大规模分布式系统的稳定性建设。冗余跨可用区部署是高可用架构的基础最重要的实践之一是确保所有软件都能够跨三个可用区运行。同时我们还确保每个应用都能够承受单个实例故障。正是这两点使可用区迁移变得更加容易当我们停止向受影响可用区发送流量时所有服务仍能继续运行。在某些情况下我们需要将实例从该可用区中移除但这只需通过几次点击重新配置自动伸缩组即可完成。我们对分布式数据库集群也采用了同样的三可用区冗余模型。所有集群都配置为复制因子为 3并确保每个副本位于不同的可用区。这样的设计让数据库集群能够很好地应对故障。当单个可用区不可用时我们无需进行人工干预。系统会将请求路由到其他可用区并在故障可用区恢复后自动修复整个副本环。故障演练工具体系持续验证系统韧性每个人在开发软件时都有良好的初衷。优秀的开发者和架构师会考虑错误处理、边界情况并努力构建具备韧性的系统。然而仅仅“考虑到”这些还远远不够。为了持续确保系统具备韧性我们必须不断测试系统的功能以及它在罕见异常事件下的应对能力。这正是我们构建故障演练工具体系的原因实例故障演练工具用于测试系统对单个实例故障的韧性延迟故障演练工具用于测试系统对网络延迟和服务降级的韧性可用区故障演练工具用于测试系统对单可用区中断的韧性。未来我们计划进一步扩展可用区故障演练能力使其能够通过一次点击完成可用区疏散从而简化故障处置过程中的决策流程。随着能力的持续提升我们还计划建设更大范围的故障演练能力用于测试系统在整个云服务地域中断时的韧性。简易工具与自动化降低故障处置成本让可用区迁移决策变得简单的关键之一是我们的内部云管理平台。借助这一平台服务负责人只需点击几下就可以按需停止向某些实例发送流量或直接删除相关实例。在故障发生时复杂、依赖人工判断且步骤繁琐的操作往往会放大风险。相反如果关键操作已经被工具化、自动化并且在日常演练中反复验证团队就能在压力环境下更快、更稳地完成处置。除了底层技术工具跨团队协作工具同样重要。例如在故障响应过程中团队可以借助 Worktile 这类通用项目协作系统将任务、文档、日历、审批和项目进度统一管理减少信息分散带来的沟通成本。接受错误通过故障复盘持续改进每次故障发生后我们都会进行事件复盘。这些复盘的目的并不是追究个人责任而是找出系统和流程中可以改进的地方。每次故障后我们都会整理一份详细的时间线然后追问自己我们有哪些地方本可以做得更好下一次怎样才能进一步降低影响怎样才能更早发现问题怎样才能更快定位问题并采取行动随后我们会根据这些问题的答案尝试解决一类问题而不是只修复最近一次故障中暴露出来的个别问题。正是通过这种方式我们逐步沉淀出了一套高可用系统建设的实践方法。对于研发团队来说故障复盘不应停留在会议纪要层面而应沉淀为可复用的研发管理资产。借助PingCode 这类智能化研发管理工具团队可以将目标、需求、开发、测试、发布和复盘知识串联起来让故障经验沉淀到 Wiki并与研发流程中的数据形成闭环从而持续提升研发效能。结论系统韧性建设没有终点在此次云服务中断事件中我们成功控制了影响范围并从中获得了新的经验教训。每次服务中断后我们都会寻找机会持续优化系统构建方式完善故障检测和响应机制。虽然我们认为自己已经构建了一套高可用、高可靠的服务体系但我们也始终清楚系统韧性的建设没有终点。无论当前系统表现如何都仍然存在持续改进和提升的空间。