博客

我们如何把部署的 502 错误降到零

每次部署 Mythex 的后端时,都会有少量请求以 502 Bad Gateway 失败。数量不多,但部署期间出现 502,意味着有人的点击没有任何反应,或者他正在盯着的构建停顿了一下。我们把它追溯到两个独立的问题:一个与部署相互打架的自愈看门狗,以及服务器停止监听与负载均衡器停止向其发送流量之间的时间差。在修复之后连续三次生产部署中,计数从 10 降到了 6,再降到 0。

架构

我们的 API 和编排器以容器的形式运行在一小组服务器上,这些服务器位于 AWS Application Load Balancer(ALB)之后。部署会一次更新一台服务器:排空旧容器,启动新容器,然后进入下一台。每台服务器上都有一个看门狗,它会检查容器是否正常运行,并重启任何未运行的容器——它的存在意义是让凌晨 3 点崩溃的进程能够自行恢复,而无需任何人被叫醒。

这两者单独来看都很合理。合在一起,却出了问题。

问题一:看门狗与部署相互竞争

看门狗每分钟运行一次,并且在一次健康检查失败时就进行「修复」。而部署会有意地排空服务,最长可达 150 秒——在此期间,健康检查「应该」失败。因此,看门狗在每一次部署期间都会触发。

大多数时候,它输掉这场竞争,无伤大雅。但有一次,它赢了:它在部署中途重写了 compose 文件(描述应当运行哪些容器的文件),结果某台服务器上完全没有了网关容器——而部署任务却报告成功。

修复方案:

  • 统一加锁。 部署现在会获取与服务器引导脚本相同的文件锁,因此看门狗与部署永远不会同时运行。
  • 四次失败才行动,而不是一次。 看门狗需要连续四次健康检查失败才会采取行动。一个正在排空的服务不再被误认为已经死亡。
  • 单一定义。 compose 文件现在只有一个来源,发布到服务器上,而不是可能相互偏离的多个副本。
  • 验证,而不是信任。 部署任务不再因为某条命令返回了结果就算通过。它会先检查每台服务器上的 API、编排器、网关和发布工作进程,然后才能成功。

问题二:服务器比流量先离开

第二个问题更加隐蔽。部署排空一台服务器时,服务器会开始用 503 响应其健康端点,让负载均衡器将其移出轮转。我们的服务器这样做了 5 秒,然后关闭。

但 ALB 只会不时地检查健康状况,并且需要连续多次失败才会停止向某个目标路由流量——从头到尾大约需要 60 秒。因此在大约 55 秒的时间里,负载均衡器仍会把真实请求发送到一台已经停止监听的服务器。这些就是我们的 502。

修复方法是让两条时间线保持一致:

  • 目标组现在每 5 秒检查一次,连续 2 次失败后将目标标记为不健康——大约 10 秒即可发现。
  • 排空过程在开始报告健康检查失败后,仍会为真实流量提供服务 15 秒,因此两者始终有重叠。
  • 这些设置写在负责配置基础设施的脚本中,而不是某次被人点击过一次的控制台里。

让各项数字相互印证

这些超时设置彼此依赖。排空时间必须长于负载均衡器发现问题所需的时间;排空加上关闭,必须在容器被强制杀死之前完成。六个月后,有人改动其中一个数字,就很容易无声无息地重新引入这个 bug。

因此,我们把这些数字之间的关系写成了测试:排空时间必须大于健康检查间隔乘以失败阈值;重新被标记为健康所需的时间必须保持较短;整个排空过程必须在容器的停止宽限期之内完成。改动其中某个数字而不同时调整其他数字,CI 就会失败。我们还对测试本身做了变异测试——把每个数字改成错误的值,并检查是否有测试能够捕获它。

测量部署很容易出错

我们最初的测量结果显示,一次干净的部署大约有 3% 的请求出错。事实并非如此。我们当时统计的是所有非 200 的响应,而排空期间健康端点返回的 503 并不是失败——那是排空在履行职责,告诉负载均衡器在它继续为真实请求提供服务时不要选中该服务器。

用户真正感受到的是 502:请求根本没有到达任何地方。只统计这些,才能得到真实的情况——在三次生产部署中分别为 10、6、0。

我们的收获

  • 自愈机制需要了解计划内的停机。 一个无法区分部署与崩溃的看门狗,迟早会与部署对抗。
  • 排空是一次握手。 服务器必须持续提供服务,直到负载均衡器可以确定已经停止发送流量为止,而这一时序是在负载均衡器上设定的,而不是在服务器上。
  • 把不变量编码为测试。 运维相关的数字会逐渐漂移。把它们彼此关联起来的测试不会。
  • 在测量之前决定要测量什么。 「错误」是错误的指标;「没有到达任何地方的请求」才是正确的指标。

如果你在 Mythex 上发布应用,这些对你都不可见——而这正是目的所在。相关阅读:你的已发布应用如何在重新发布时保持在线。

Mythex · Pricing · 用 AI 构建任何东西 · 网站和应用模板 · Mythex 对比 · AI 应用构建术语表 · 免费的 AI 应用构建工具 · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 繁體中文(香港) 繁體中文(台灣)