原文链接:https://hetarth02.hashnode.dev/how-8-bytes-broke-production
前阵子我接到了一个项目,这个项目属于教诲技能领域,许多大公司都在利用,我们姑且称之为“革命性教诲知识技能(Revolutionary Education Knowledge Technology)”,简称“REKT”。
关于 REKT 项目,我有许多故事想与大家分享,但还是先从这个故事开始吧:一个关于区区 8 个字节如何导致全体生产环境崩溃的故事。

背景先容
那是操持进行生产支配的前一天,如果我没记错的话,也是我正在玩的一款游戏进行重大内容更新的前一天。我无法详细先容项目的实际细节,但可以大略概括一下:你可以把这个项目想象成一个类似于 Udemy(一个在线学习和传授教化市场)的平台,但它供应的是针对企业的专有领域内容。在 REKT 项目中,我卖力实现许多功能,个中之一便是创建一个管理/内容管理面板来管理教诲模块——就像在 Udemy 中,一个模块包含许多讲座和内容供用户选择,REKT 也是如此。
明确一点,我并不是这个项目的第一批开拓职员。在我之前,有一组开拓职员已经搭建了全体“架构”,并为 REKT 选择了技能栈。我认为,节制根本知识比学习特定措辞更为主要,由于对我来说,办理问题的方法过程比知道办理问题的语法更主要。举个大略的例子,如果我须要重复做某件事情,我就会想到用循环。在这个例子中,循环便是办理问题的方法,至于如何详细实现循环,则因不同的编程措辞而异。
// For loop in javascript
for (let i = 0; i < 10; i++) {
console.log(i);
}
# For loop in python
for x in range(0, 10):
print(x)
// For loop in PHP
for ($x = 0; $x <= 10; $x++) {
echo $x;
}
因此,我更看重培养办理问题的思维办法,而不是专注于办理问题的特定措辞或语法。
言归正传,当时我对前端、后端和做事器从 MVC 和单体架构的角度有一些理解。幸运的是,我通过 SvelteJs 学到了组件驱动的前端方面知识,不幸的是,我还没机会深入研究 ReactJs 和 VueJs 等框架。你猜猜 REKT 项目的技能栈是什么......前端利用 ReactJs,后端利用 Fastify,并紧密依赖于 AWS 生态系统;最主要的是,这统统都是无做事器的,由 Terraform 进行管理。
而当时,我对无做事器的理解仅仅是:一旦涌现要求,它就会启动一个类似做事器的运行时环境。
此外,关于全体架构的构成以及利用了哪些做事的文档非常少,险些可以说是没有。
支配顺利,开始大胆玩游戏
我不再过多提及过往,快进到功能支配的那一天。我和质量担保团队对这个功能进行了详尽的测试,险些覆盖了所有可能的情景。统统看起来都很顺利,在得到经理的批准后,我们当天一早就将其推送莅临盆环境中。支配完成后,质量担保团队开始在实时环境中进行测试。可能是由于过度自傲、天真,也可以说是缺少履历,我毫无顾虑地安装了我正在玩的游戏更新并开始玩了起来。经理也看到了我在玩游戏,但由于统统都很顺利,他也就没太在意。上午的韶光进行得非常顺利,生产环境中的所有功能都在正常事情,我们对其进行了多次验证和测试,并奉告客户可以开始利用了。
、
溘然搞砸(REKTed)了!
接下来是事情日的后半段。我刚吃完午饭回来,正准备处理其他工单,溘然团队谈天里弹出了一条:
“保存内容时问题没有添加。” —— 客户 当下,我的脑海中急速涌上了无数想法:这怎么可能?我们在开拓、预发布和生产环境都进行了多次测试,这肯定是个误会。
“可以让他们打消浏览器缓存或逼迫刷新后再试一次吗?” —— 我
“我们已经在隐身模式下运行了。” —— 客户
我想,这下糟了!
我立即打开了开拓支配环境并进行检讨:我创建了一个课程,添加了一些带有几个问题和选项的内容(测验),点击提交按钮,结果——成功保存了!我急速又试了一次,每次都能完美保存。我把我的操作过程录频并发到了团队群里:
“我刚试了一下,它没问题啊。” —— 我 紧接着,客户也发送了一段显示问题的屏幕录制。此时,我和质量担保团队已经在三个不同的环境中逐一考试测验了每一种情景,统统都运行得非常好。
韶光一分一秒地流逝,只管我们努力探求问题所在,但始终没有取得任何打破。为了找出为什么客户无法保存内容的缘故原由,我和质量担保团队乃至还创造了一些其他的重大 Bug。
明明上午都统统顺利,我还有空去玩游戏;但到了那天晚上 11 点,我们都还在找那个 Bug。当时我们太累了,什么都想不起来,就算试着添加一些补丁也都不起浸染,我们开始感到绝望。
“我们彷佛没有什么进展。本日就到这里吧,来日诰日带着复苏的头脑再来看这个问题。” —— QA 他说得对,我们一整天都在反复做同样的事情,已经陷入了思维定势。
、
得到资深开拓者的帮助
就在我们准备结束这一天的事情时,发生了一件有趣的事情,为我终极办理这一系列问题铺平了道路。一位资深开拓者在完本钱身的事情后还有一些韶光,他主动提出帮助我们调试这个问题。我们尽力总结了当前的情形,但实际上连我们自己都不知道为什么内容无法保存(至于其他 Bug,我和 QA 决定先保密!
)。这位资深开拓者乐意加班来帮我们,我们既以为不好意思,又有些许宽慰。他并没有做出什么特殊惊人的举动,只是打开了开拓工具,让我输入数据并保存,统统都正常保存。接着,他又让我重现客户碰着的问题,我也欣然照做。
“我以为问题就在这里……” —— 资深开拓者 他向我们展示了两种情形下的要求负载大小:
成功情形下:~8,192 字节
失落败情形下:~8,200 字节
“不,这不可能是问题所在。” —— 我
“这肯定不是问题,只不过 8KB 而已,一定还有其他缘故原由。” —— 我再次强调
只管心里这么想,我们还是决定结束这一天的事情。不过,这个线索给了我们一个新方向去思考第二天该如何办理这个问题。
求求了,下次记得写点文档!
我知道大多数情形下,开拓者都不愿意写文档。但至少,请花 5 分钟韶光考虑一下未来掩护你代码的人吧!
你真的希望他们写一篇约 2 千字的文章来抱怨因短缺基本文档而感到无比抓狂吗?好吧,再次言归正传。第二天早上 7 点旁边,我们带着焕然一新的心情早早来到办公室。有一件事让我铭心镂骨,那便是 8KB 的负载大小切实其实是胡扯(没有对那位资深开拓者不敬的意思)。于是我考试测验在 fastify 中扩展 POST 主体的大小,重新支配了后端,但同样的问题依然存在。
既然如此,我心想先把这个问题放一放,办理一些其他 Bug,以免它们被客户创造。于是,我暂时搁置了这个问题,转而办理了其他 Bug。虽然这些 Bug 也并不随意马虎办理,但它们并不是完备的黑盒,我可以轻松地追踪代码、找到逻辑中的一个小毛病。就这样,我逐一修复了其他 Bug,虽然紧张问题仍未办理,但我终于有了一些希望:有时候,小小的胜利能够改变你的生理状态,调度你的思维办法——对我来说,确实如此。
后来,我又一贯在查看前台和后台的缺点日志,但没有创造任何缺点的迹象。对我来说,这真是一个黑盒,就算我们可以重现 Bug,它也没留下任何可追踪的线索。
换个角度思考
……等等,为什么我没有收到这个特定要求的日志?它明明从前端发出,有时乃至能到达后端。假设 8KB 的问题是对的,这就解释有什么东西阻挡了要求到达后端。那会是什么缘故原由呢?我们并没有设置任何做事器...
“我们该当撤销许可所有 CORS 设置的变动,由于那不屈安。”——QA 对了!
!
!
安全,安全性,我们是否有针对路由的安全组或任何具有特定规则的东西?我登录 AWS 面板,进入了安全组,但什么也没找到,就连谷歌搜索也没帮上太多忙。然后我溘然想到,既然要求没有到达后端,那么肯定有什么东西在保护它。由于是无做事器架构,我认为安全组不太可能是问题所在。那还有什么可能呢?我在谷歌上搜索“AWS 网站安全产品”,然后在传输层/网络层中探求阻挡要求的东西,结果创造它便是这个问题的罪魁罪魁......AWS Web 运用防火墙(WAF)
随后,统统开始变得明朗起来。我搜索了“aws waf 主体大小限定”,并找到了答案。
“我们也利用了 AWS WAF 吗?”—— 我、QA、经理,可能还有客户 不仅我感到意外,全体团队都对此感到惊异。好在修复这个问题实在非常大略,只需登录 AWS 掌握台,变动 WAF 规则以许可更大的要求负载,然后再次测试:终于统统正常了!
不过等我清理了一些代码后重新支配,再次进行了测试……结果又失落败了。
什么鬼?!
我心想。哦对了,由于全体根本举动步伐是由 Terraform 管理的,以是它重置了 WAF 规则的设置。好吧,暂时先手动变动它,该当就没问题了!
至于自动化的问题,就留给未来的我来办理吧。总结
这统统办理之后,我花了大约一个小时旁边的韶光,详细记录了全体事宜的过程,希望这篇文章可以帮助未来在 REKT 项目中碰着类似问题的任何人。