闹钟响的时候你睡得正香。现在是凌晨3点。你擦擦眼睛,看看手机。你知道有些不对劲。大错特错。
网站瘫痪了。您的应用程序已损坏。房间里唯一的光来自你的电脑显示器。系统中的Gremlin可能隐藏在任何地方,找到它是您的团队的工作。
作为一个为多家DevOps初创公司管理公关的人,我看到这个故事一遍又一遍地上演。即使是最有经验的工程师,光是一次重大停机的声誉成本就足以让人感到恐惧!
但事实是,每家公司都有系统故障。我们离让在线系统看起来更像公用事业公司还有一段路要走,在这种情况下,只要轻轻一按开关,它就能正常工作。因此,分享故事和将失败正常化(例如,透明和无可指责的事后处理)是该行业的积极趋势;它让每个人都不那么害怕和孤独。
我不打算引用有关停机成本的通用数字。对亚马逊来说,这可能是每小时数百万美元;对你的公司来说,如果处理迅速,可能只会限制在令人沮丧的客户体验上。但最终,这些情况会让企业赔钱,损害声誉,耗尽工程资源,并激发人们对竞争的兴趣。
因此,本着万圣节的精神,更重要的是本着分享经验以更好地防止未来发生这种情况的精神,让我们来看看CTO们自己讲述的六个可怕的停电故事。
“推盘不可能往下推。我们的推送在排队,而我正在接受推送。“。
“已经五天了,推盘还是往下。人们正在将各种任务归档。“
…。所以我很不情愿地开始四处打听。我们所有的推送指标看起来都比较正常,我发送的每一次测试推送都是及时交付的。然而,支持团队是对的-人们整整五天来一直在抱怨推动没有成功。到底是什么呢?
这些都是Android推送通知,Android设备需要向服务器打开一个套接字才能订阅推送通知。我们有数以千万计的Android设备,所以我们在一个自动伸缩组中运行推送通知服务。为了在整个组中实现连接负载平衡,我们使用了循环DNS,而要增加容量,我们只需增加ASG[自动伸缩组]的大小即可。最终,我们发现投诉是在我们最后一次增加ASG大小的时候开始的,所以这是一个很好的线索。另一条线索是,所有抱怨的人似乎都在东欧。我们要求他们中的一些人运行详细的跟踪,就在那时我们了解到dns记录将以…的形式返回。失踪了吗?
结果发现,当我们增加ASG的大小时,循环DNS记录超过了UDP数据包的大小。通常这没什么大不了的;协议说在这种情况下应该退回到使用TCP。它确实发生了,对几乎每个人来说都是如此。除了罗马尼亚一台主要路由器后面的用户。我们将该记录的DNS从route53委托给一个小型的本地python DNS服务器,该服务器允许我们返回4个Android推送通知服务器的随机子集,然后一切都恢复正常。💀。
停电发生在一个周五的下午,当时我们正准备去万圣节欢乐时光。传来的页面显示,我们只为500提供服务-这对客户来说是一种非常非常糟糕的体验。经过一些挖掘,我们意识到我们的主机已经填满了他们的磁盘,我们开始失败,因为我们不能写日志(也很可怕,因为我们是在盲目飞行)。
我们最终刷新了主机,实现了日志轮换以防止将来发生这种情况,并创建了警报以警告我们是否再次接近。但最有趣的是,我们让一位工程师为我们的平台编写了一个新的Gremlin:Disk Gremlin,以确保我们可以主动执行修复,确保我们不会再以这种方式失败。然后,我们自动化了该测试,而该测试仍然挥之不去,直到今天仍在我们的生产环境中随机运行。😱。
还记得那个关于服务器每天在同一特定时间停机的都市传说吗?经过几周的调查,有人看了监控录像…。发现女佣正在断开服务器连接吸尘器!嗯,我们都知道,衣柜里的Gremlin并不总是像我们最初想象的那样可怕或神秘:)。
每周有好几次,我们都看到后端的延迟指标达到了顶峰。每次我们调查它时,我们都会注意到其中一个表被锁定,并且所有查询都不断超时。我们想知道:我们的一个客户是否不间断地重新部署他们的应用程序?主要的疑点是一个复杂的查询,它获取我们所有客户的服务器信息的列表,这样他们就可以选择要调试的服务器。我们开始优化该查询,看到了巨大的改进,但这些延迟峰值仍在不断发生。
几周前,在参加每周一次的“客户成功简报会”时,延迟高峰再次出现,这对我打击很大。我从应用程序的后台注意到一个我们很少使用的查询,它非常慢,因为我们从来没有优先修复它(它几乎没有使用过)。显然,我们的客户成功经理一直在为会议收集数据,每次查询返回得不够快时,他都会不停地点击刷新和重试。那个很少使用的查询锁定了我们的数据库,并挑战我们客户成功经理的理智!回顾数据,我们确认所有延迟峰值都与客户成功简报保持一致。最终,在优化该查询大约20分钟后,一切都恢复正常。🎃
那是旧金山一个晴朗阳光灿烂的日子。我在一家小互联网公司工作,突然我们的应用程序停止为我加载。不只是一个视图,而是整个应用程序。重新装弹很辛苦,但运气不佳。我环顾四周,我的队友们也很困惑;这个应用程序也不能为他们工作。我们的用户没有抱怨(还没有吗?)。但不管怎样,我们还是开始挖坑了。那一天还没有进行任何部署,基础设施也没有改变;然而,它在各种操作系统类型和浏览器中都是一致崩溃的。会有什么改变呢?
我们在一个关键的(但很无聊而且没有永远改变的)API调用中发现了一些错误,如果没有这些错误,应用程序将无法加载。但为什么这些错误只发生在公司的员工身上呢?为什么是现在?原来,对于内部用户,该接口返回了一些额外的数据…。额外的数据在过去几周内一直在缓慢增长,直到那天下午最终超过请求的最大有效负载大小。👻。
我们所依赖的AddTrust Root证书颁发机构(CA)大约在凌晨4点过期。太平洋时间2020年5月30日星期六上午。
当时,作为迁移到Kubernetes的一部分,我们正在将我们的一些基础设施过渡到一个非营利性的证书颁发机构“让我们加密”(We‘s Encrypt)。旧式系统日志客户端需要AddTrust/UserTrust/Comodo。除了为主要云合作伙伴运行多个全球环境外,我们还运行自己的SaaS环境。在我们的SaaS环境中,到处都使用单个证书链,包括我们的接收端点、系统日志端点和Web应用程序。我们认为我们已经为这个根证书过期…做好了准备。我们没有。
证书链快速入门:所有基于证书的安全性都依赖于信任链。浏览器和操作系统附带这些根证书的信任存储区。
LogDNA链:AddTrust Root CA(5月30日到期)->;UserTrust CA->;Sectigo->;*。Logdna.com。
UserTrust CA本身也是许多浏览器的根信任存储的一部分,因此即使AddTrust过期,它也会被忽略,因为通向UserTrust CA的链仍然有效。
原来,旧的遗留系统将只看到LogDNA链,如果四个证书中的任何一个过期,它就被认为是无效的链。它们也不会将UserTrust识别为受信任的根证书。
我们收到的所有支持票证都提到我们的v1代理不再向我们的接收端点发送日志,但是我们的v2代理和其他基于rest API的客户端的现代实现都工作得很好。
我们错误地开始对v1代理进行更新。具有讽刺意味的是,由于相同的AddTrust Root CA到期,我们的CI/CD提供商自己也发生了故障,这进一步使我们推出该代理变得更加复杂。一旦我们意识到问题出在实际的证书链上,以及旧的遗留系统在该链上的行为如何,我们就会通过切换到一个基于“让我们加密”的新证书链来快速纠正这个问题。🧟。
全面的站点停机是可怕的-但它们不会让您的皮肤像随机的、不可预测的故障那样爬行。我当时正在开发Twitter的移动网络版本,我们收到了一些请求,对于一些随机倒霉的露营者来说,每当他们访问该网站时,都会导致一个可怕的错误页面。对于其他人来说,天空是蓝色的,鸟儿在啁啾。但时不时地,会有其他人被击中。而且,一旦他们被击中,他们就陷入了绝望的深渊,无法阅读手机上的任何推文。
慢慢地,随着这些受损账户数量的增加,500开始攀升到临界水平。我们可以看到,我们正在使用的新库无法解析具有特定字符的会话cookie。所以每次你重新登录的时候,你都是在掷骰子,被这个讨厌的漏洞咬了一口,如果没有重新设置手机cookie的神奇力量,你就不可能被治愈。最终,我们修复了图书馆中的错误,每个人都可以回去阅读他们的推文…。正如我们所知,这本身就是一件非常可怕的事情!🕸️