跳转至主要内容

2022 年 7 月 13 日犹他州服务中断更新

从 7 月 13 日(星期三)UTC 时间大约 18:00 开始,Deno 公司提供的几项服务在犹他州(us-west3)经历了区域性服务中断,持续时间略超过 24 小时。在此期间,犹他州地区的用户在访问 Deno Deploy 上托管的项目时遇到了故障,包括许多 Deno Web 属性。

我们已经得出结论,此次中断是由我们的负载均衡服务引起的。这篇文章详细介绍了究竟发生了什么,以及我们正在采取哪些措施来防止将来再次发生这种情况。

在尝试恢复 us-west3 地区在线后,7 月 15 日 15:30 UTC 至 16:00 UTC 之间也遭受了较短的服务中断。新创建的负载均衡器工作了几个小时,但最终遇到了相同的问题。在此期间,Deno Deploy 上托管的项目(包括许多 Deno Web 属性)在该地区不可用。

所有服务现在都已恢复正常运行。没有数据丢失。我们认真对待此类服务中断,并对由此造成的不便表示诚挚歉意。

影响

在约 24 小时的时间内,us-west3 地区的一些用户无法访问 dash.deno.com 和 Deno Deploy 项目,包括 deno.com 和 deno.land。该地区位于犹他州,为周边地区(包括一些邻近州)提供服务。在第二次事件中,影响相同,但持续时间短得多;不到 30 分钟。

只有 us-west3 地区受到中断。所有其他地区在整个事件中都正常运行。此外,Subhosting 未受影响。

事件时间线

7 月 13 日大约 18:45 UTC,我们开始收到少量用户的服务中断报告。我们调查了服务的状态,但无法证实任何报告。我们所有的状态监控和测试都报告一切运行正常。

在服务中断期间,我们继续监控我们的服务状态,并与一些受影响的用户合作,以缩小问题根源。

7 月 14 日 19:14 UTC,我们能够确定问题出在 us-west3 区域,然后我们将其下线,将流量定向到附近的其它区域。

7 月 15 日 11:30 UTC,我们尝试使用新的负载均衡器实例将该地区恢复在线。

7 月 15 日 16:00 UTC,负载均衡器进入与之前相同的故障状态,我们再次禁用了该地区。在该地区的监控得到改善且问题得到更永久的修复之前,该地区将保持禁用状态。

根本原因

进入 Deno Deploy 网络的最终用户请求会通过各种负载均衡器,最终到达可以执行 JavaScript 代码以响应请求的服务。

负载均衡器和后端服务的不同层使用 etcd 来执行服务发现。当服务可用性状态更改时,服务会向 etcd 集群声明自身。其他服务(如这些负载均衡器)从 etcd 检索健康的后端服务列表。它们还 watch 监视已声明的服务列表,以便在给定服务变为可用或离线时得到通知。然后,负载均衡器使用此列表来决定将流量路由到哪些后端服务。

在本次服务中断期间,其中一个区域负载均衡器设法断开了与 etcd 的连接,但应用程序没有注意到。我们预计这种连接会因网络故障、超时等原因而经常断开。因此,应用程序被编程为自动重新连接,并在失败时自行关闭。

在没有此连接的情况下,负载均衡器无法接收来自 etcd 的更新。这导致它与系统的其余部分“不同步”,并且不知道任何健康的后端来定向流量。

负载均衡器没有任何健康的后端服务的情况并非十分罕见,因此负载均衡器知道如何处理这种情况。如果没有健康的后端,它将从网络中取消声明自身,以防止请求最终到达这个“死胡同”。

由于负载均衡器中的设计疏忽,在这种特定情况下,它没有从系统中取消声明自身。这导致负载均衡器继续接收来自上游负载均衡器的流量,但没有任何地方可以定向流量。这导致流量被完全丢弃。

下一步是什么?

此事件清楚地表明我们的监控系统中存在一些盲点。我们正在研究减少这些盲点的方法,并改进我们在各个区域内的监控能力。

此外,我们很难缩小导致服务中断的地区范围,因为发生故障的负载均衡器位于网络堆栈的早期阶段(TCP 负载均衡器)。它不记录任何关于连接断开的诊断信息,也没有返回通道来向用户返回诊断信息(不像 HTTP 负载均衡器,它可以返回响应标头)。我们正在努力改善这里的监控情况。

我们目前还在负载均衡系统中进行一些架构更改,以完全防止此类故障的发生。