你已沉沉睡去,却突然被闹钟的铃声惊醒。揉揉眼睛,你点亮手机,发现是凌晨三点。好吧,又出问题了。

网站已经关闭,应用程序已经损坏,房间里唯一的光亮来自你的电脑屏幕。系统中的“小幽灵”可能藏在任何地方,你的职责就是带领团队把它们找出来。

摄图网_400454522_banner_木木酱卡通形象电脑蓝屏配图(企业商用)(1).jpg

之后,修复一切,越快越好。


作为负责帮助各类 DevOps 初创企业打理公关事务的角色,这样的状况在我眼前不断重演。即使是经验最丰富的工程师,也很有可能因为一次重大事故而留下伴随终身的心理阴影。


但不可否认,每一家企业都会遭遇系统故障。而且,我们距离让在线系统像电力等即开即用的传统设施一样触手可及还有很长的路要走。因此,整个行业开始积极分享故障问题与真实故事(包括建立起透明且非指责性事后取证),这也让每位从业者逐渐摆脱了宕机事件带来的恐惧感与孤独感。


这里我们不会粗暴援引冷冰冰的数字,毕竟 Amazon 每小时可能遇到的上百万个问题,而小型企业只是引发糟糕客户体验。但无论规模如何,企业最终总会蒙受金钱损失、声誉损失、工程资源浪费,并导致市场地位下降。


下面,我们就单从分享经验与加以预防的思路,听听 CTO 们自己讲述的六个恐怖宕机事件。

Charity Majors,Honeycomb 公司 CTO


“通知推送失败!”


“不对吧,没问题啊。”


“有问题,客户们已经开始抱怨,推送功能中断了。”


“推送功能不可能中断。我们的推送仍在队列中,我还能收到各种推送呢。”


“已经五天了,推送效率仍然很低。大家正在不断提交各种问题。”


……没办法,既然都这么说了,我只能到处找找问题。但我们所有的推送指标看起来都比较正常,我发送的每条测试推送也都能及时完成交付。但客户支持团队的说法也没错——过去五天以来,人们确实一直在投诉推送失败。到底怎么回事?


这里说的是 Android 推送通知。Android 设备需要保证指向服务器的套接字始终开启,才能正确订阅推送通知。我们拥有数以千万计的 Android 设备,因此需要在 autoscaling 组里运行推送通知服务。为了对整个组内的连接进行负载均衡,我们还使用了循环 DNS;要想增加容量,我们只需要增加 ASG(auto-scaling 自动伸缩组)的大小即可。最终,我们发现投诉来自上一次增加 ASG 大小,这应该是个有用的线索。另一个线索在于,所有的客户投诉似乎都来自东欧。我们抽取其中几位,邀请他们进行更详细的跟踪,并发现 DNS 记录似乎发生了丢失。


事实证明,当我们增加 ASG 的大小时,轮询 DNS 记录超过了 UDP 数据包的大小。正常来说这其实没什么问题,协议上说发生这种情况时,应该会返回继续使用 TCP。事情也的确如此——除了少部分区域。罗马尼亚一台主路由器出了问题,因此我们将用于该记录的 DNS 通过 Route 53 服务指派给了另一台小型本地 Python DNS 服务器,由该服务器返回由四个 Android 推送通知服务器的随机子集。一切恢复正常,万幸。


Matthe Fornaciari,Gremlin 公司 CTO


宕机发生在星期五下午,当时我们正准备去参加万圣节狂欢。警告页面出现,经过一番调查,我们意识到主机中的磁盘空间已经被耗尽,并因无法继续写入日志而开始出现故障。这非常可怕,因为我们无法了解当前的运行状态。


最终,我们刷新了主机、引入日志轮替以预防再次发生此类问题,并创建警报以随时提醒磁盘空间使用情况。除此之外,我们还指派一位工程师为平台编写了新的 Gremlin。这一磁盘 Gremlin 能够帮助我们主动进行修复,彻底消除后续可能出现的同类故障。最后,我们实现了整个测试流程的自动化,目前这项测试仍然存在,直到今天仍在我们的生产环境中随机运行。


Liran Haimovitch,Rookout 公司 CTO


还记得服务器每天会在同一特定时间点发生宕机的都市怪谈吗?经过几个礼拜的调查,人们从监控摄像头中发现……原来是保洁人员会定期拔下服务器的电源,再接上吸尘器!哈哈,其实运营故障就是这样,看似可怕、背后却往往有着很多黑色幽默般的深层原因。


最近,我们也遇到了类似的状况。


每个礼拜,我们都会多次发现后端延迟指标出现持续增长。而每当进行调查时,我们都注意到其中一个表被锁定且持续出现查询超时。我们很好奇,这是有哪位客户在不停地重新部署自己的应用程序吗?这种溯源查询相当复杂,需要获取所有客户服务器信息的列表,借此判断哪些服务器有待调试。我们开始优化这项查询并获得了巨大的改进,但延迟峰值问题始终没能得到解决。


几个礼拜之前,在参加每周“客户成功简报”时,等待时长再次出现峰值。突然之间,我意识到应用程序的后台中存在一个我们几乎从不使用的查询,它的速度也的确很慢,我们从来没有考虑过优先加以修复(毕竟很少使用)。显然,我们的客户成功经理一直在收集会议数据,在每次查询返回结果的速度不够快时,他都会不断刷新并重试。就是这项极少使用的查询锁死了我们的数据库,最终造成了神秘的延迟现象。通过数据审查,我们确认所有延迟峰值都与客户成功简报会议相符。于是,我们优化了该查询。大约 20 分钟之后,一切恢复正常。


Daniel “Spoons”poonhower,Lightstep 公司 CTO


那是旧金山阳光明媚的一天,我在一家小型互联网企业工作。突然之间,应用程序停止了正常加载。不只是当前视图,是整个应用程序都陷入瘫痪。我重装了一下,但还是不行。我望了望四周,同事们显然也遇到了问题。虽然用户还没有发出投诉,但我们必须赶快行动。那天我们没有进行任何部署,基础设施方面也没做出调整。但应用本身在各种操作系统和浏览器上都一概不给面子……到底出了什么问题?


我们在几项关键 API 调用中发现了一些错误,但解决之后,应用仍然无法加载。更要命的是,为什么只有公司内部员工遇到了无法加载的问题?事实证明,该 API 会为内部用户返回一些额外的数据。而过去几周之内,这些额外数据一直在缓慢增长,最终在当天下午超过了请求的最大有效载荷。


Lee Liu,LogDNA 公司 CTO


我们使用的 AddTrust 根证书分发机构(CA)于 2020 年 5 月 30 日星期六约凌晨 4 点时过期了。


当时,我们正将部分基础设施迁移至非营利性证书分发机构 Let’sEncrypt,这也是公司 Kubernetes 迁移计划的一部分。旧版 Syslog 客户端需要使用 AddTrust/UserTrust/Comodo。除了由云合作伙伴提供的全球基础设施环境之外,我们还运行有自己的 SaaS 环境。在这套内部 SaaS 环境中,到处都在使用同一条证书链,包括我们的接收端点、Syslog 端点以及 Web 应用程序等。我们以为自己已经为根证书到期做好了准备……但事实证明,并没有。


证书链快速入门:所有基于证书的安全机制都依赖于信任链。浏览器及操作系统附带有根证书的信任存储库。


LogDNA 链:

AddTrust 根 CA(5 月 30 日到期) ->UserTrustCA ->Sectigo-> *.[logdna.com](http://logdna.com/)

复制代码


UserTrustCA ->Sectigo-> *.[logdna.com](http://logdna.com/)

复制代码


或者,这只是我们的一厢情愿。


事实证明,旧有系统只能识别到 LogDNA 链。如果四份证书中的任何一份过期,则该链将成为无效链。此外,旧系统不会将 UserTrust 识别为受信根证书。


我们收到的所有支持通知,都提到 v1 代理将不再将日志发送至我们的接收端点;但我们的 v2 代理及其他基于 REST API 的现代客户端实现都能够正常工作。


带着错误的预判,我们对 v1 代理进行更新。更加讽刺的是,由于同样的 AddTrust 根 CA 到期问题,我们的 CI/CD 供应商也出现了问题,并导致代理的部署流程变得更为复杂。在意识到问题出在实际证书链与旧有系统无法兼容之后,我们快速切换至基于 Let’s Encrypt 的新证书链、成功修复了系统。


Tina Huang,Transposit 公司 CTO


全站宕机确实非常可怕,但更可怕的是那种随机出现、无法预测的故障。当时,我正在处理 Twitter 的移动版本。有客户反映称,对于某些在户外使用这款应用的群体,每当访问网站时看到的只有错误提示页面。但问题的发生几率不高,绝大多数用户仍然能够看到正常的界面。这就很让人头大,我们肯定不能直接忽略这个只影响少数群体的严重问题。


慢慢的,受影响账户的数量开始增加,500 服务器内部错误量也开始攀升至临界水平。可以看到,我们当前使用的新库无法解析具有特定字符的会话 cookie。因此,每当用户重新登录时,都会被这个问题所困扰。除非清空手机上的 cookie,否则问题将反复出现。最终,我们修复了库中的错误,让每个人都能正常阅读自己的推文……回想起来,这真是段可怕的经历!


原文链接:

https://thenewstack.io/6-scary-outage-stories-from-ctos/