工程师称在生产环境测试代码是超能力而非疏忽
来源标题:All of us test in production all the time (2019)
一位工程师撰文指出,所有优秀工程师其实一直在生产环境测试代码,这本身并非坏事。问题在于团队不愿承认这一现实,因而没有投入工具和培训来安全地进行生产环境测试。文章认为,测试的核心是减少不确定性,检查已知、过往和可预测的失败。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
“我并不总测试自己的代码,” 世界上最有趣的男人(The Most Interesting Man in the World)在史上最经久不衰的科技梗之一中沉思道,“但当我测试时,我在生产环境里测。”
自从2013年(大概是吧?)第一次看到这个梗,我就一直在笑。它不只是好笑,简直笑死人!
从那以后,“在生产环境测试”就成了我们与生产服务交互时所有不负责任做法、或者为赶上线而偷工减料的代名词——这都得怪那位最有趣的男人和他那让人无法抗拒的梗。
因为,坦白说,我们所有人一直都在生产环境里测试。(至少,优秀的工程师是这样的。)这本身并不坏,也不是疏忽的表现——工程师每天与生产环境打交道,观察自己写的代码如何与基础设施和用户交互,看到那些他们永远无法预料的互动方式,这绝对是一件好事。
在生产环境测试是一种超能力。真正害了我们的,是我们不愿承认自己在这么做,也不愿投入工具和培训来安全地做这件事。
从本质上讲,测试就是通过检查已知故障、历史故障和可预测故障来减少不确定性——也就是所谓的“已知的未知”。如果我在特定环境中运行一段确定性代码,我期望结果能以可重复的方式成功或失败,这让我对该代码在该环境中有了信心。很好。
现代系统由这些可测试的构建块组成,但还包括:
特定的网络栈,带有特定的可调参数、固件和网卡 连接内不可靠或根本不存在的可串行化 特定的CPU及其缺陷;多处理器 所有依赖项的特定库版本 特定的容器或虚拟机及其缺陷 各自带有特定退避、重试和超时策略的客户端 特定的时刻:一天、一周、一月、一年、十年中的某个时间点 死亡、审判以及其他现实世界事件
当我们说“生产环境”时,通常指的是所有这些事物乃至更多的集合体。尽管我们竭尽全力去抽象掉那些烦人的底层细节——比如EC2实例上eth0网卡的固件版本——但我在这里要让你失望了:在某些不可预测的场合,你仍然不得不关心这些东西。
如果测试是关于不确定性的,那么你每次部署到生产环境时都在“测试”。毕竟,每次部署都是制品、环境、基础设施和时间的独特且不可复制的组合。等你测试完,它已经变了。
一旦部署,你测试的就不再是代码,而是系统。
一旦部署,你测试的就不再是代码,而是系统——由用户、代码、环境、基础设施和某个时间点组成的复杂系统。这些系统有着不可预测的交互,缺乏任何合理的排序,并产生始终且永远超出你确定性测试能力的涌现特性。
“我并不总测试,但当我测试时,我在生产环境里测”这句话似乎暗示你只能二选一:要么在生产前测试,要么在生产中测试。但这是个假两难。所有负责任的团队两种测试都会做。
然而我们只承认第一种测试,那种“负责任”的测试。没人承认第二种,更别说讨论如何更好、更安全地做这件事了。没人投资于自己的“生产环境测试”工具。这就是我们做得如此糟糕的原因之一。
对我们大多数人来说,世界上最稀缺的资源是工程周期。每当我们选择把时间花在某件事上,就隐含地选择了不做其他数百件事。选择把宝贵时间花在哪里,是任何团队能做的最困难的事情之一。它可以成就或毁掉一家公司。
作为一个行业,我们系统性地在生产系统工具上投入不足。我们谈论测试的方式,以及我们实际与软件协作的方式,都完全集中在防止问题到达生产环境上。承认有些bug无论如何都会到达生产环境,一直是一个不可言说的现实。正因如此,我们发现自己极度缺乏方法来理解、观察和严格测试我们代码在其最重要的黄体期——开个玩笑,我是说开发周期中最关键的阶段。
承认有些bug无论如何都会到达生产环境,一直是一个不可言说的现实。
让我讲个故事。2019年5月,我们决定为整个Honeycomb生产基础设施升级Ubuntu。Ubuntu 14.04的AMI即将停止支持,而自从2015年我第一次搭建基础设施以来,它就没有被系统性地推广过。我们做了所有负责任的事:我们测试了它,写了脚本,先推广到预发布和内部试用服务器。然后我们决定推广到生产环境。事情没有按计划进行。(有过吗?)
有一个问题:当引导脚本还在运行时,整点执行的cron任务会出问题。(我们大量使用自动伸缩组,数据存储节点互相引导启动。)结果发现,我们只在一小时的60分钟中的50分钟里测试了引导过程。自然,我们看到的大多数问题都出在存储节点上——当然是这样。
还有数据在rsync过程中过期的问题。Rsync在看不到段文件的元数据时会恐慌,反之亦然。还有关于埋点、优雅重启和命名空间的问题。都是老一套。但这些都是负责任地在生产环境测试的绝佳例子。
我们在模拟环境中做了适当数量的测试。我们在非生产环境中尽了最大努力。我们内置了保护措施。我们实践了可观测性驱动开发。我们添加了埋点,以便跟踪进度和发现问题。我们在推广时用肉眼密切监视,寻找任何不熟悉的行为或可怕的问题。
(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。