我最近写了一篇文章,关于为什么我们现在都是分布式系统工程师。 令我惊讶的是,很多人反对你在生产环境中必须测试大型分布式系统的观点。
尽管我们一直都在这样做,但生产环境测试似乎名声不好。
也许 我们将其与牛仔式工程联系起来。 我们听到“生产环境测试”就认为这意味着没有单元测试、功能测试或持续集成。
在生产环境之前尝试找出问题是好的——我们也应该这样做! 但这些事情并非互斥。 以下是关于生产环境测试的一些考虑事项。
1. 你已经在这样做了
有很多事情你已经在生产环境中测试了——因为你没有其他方法可以 测试它们。 当然,你可以启动各种系统组件或整个系统的克隆,并捕获真实流量以离线重放 (系统测试的黄金标准)。 但许多系统都太大、太复杂且成本过高而无法克隆。
想象一下尝试启动一个 Facebook 的副本进行测试(及其多个全球分布式数据中心)。 想象一下尝试启动国家电网的副本。 即使你成功了,接下来 你需要相同数量的客户端、相同的并发性、相同的流水线和使用模式等等。 用户流量的不可预测性使得模拟变得不可能; 即使你可以完美地重现昨天的流量,你仍然无法预测明天的流量。
很容易陷入关于克隆环境的无谓争论,而忽略了真正重点:只有生产环境才是生产环境,并且每次部署到那里时,你都在测试部署代码 + 软件 + 环境的独特组合。 (问问任何曾经自信地部署到“Staging”,然后部署到“Producktion”(原文如此)的人)。
2. 其他所有人也是如此
你无法启动 Facebook 的副本。 你无法启动国家电网的副本。 有些东西就是不适合克隆。 这没关系。 你根本无法有效地模仿规模和混乱的特性,而这些特性会梳理出你关心的长长的、细微的错误或行为。
你不应该尝试。
Facebook 也没有尝试启动 Facebook 的副本。 他们投资于工具,这些工具允许成千上万的工程师每天安全地部署到生产环境,并观察人们与他们编写的代码进行交互。 Netflix 也是如此。 所有有幸摆脱了认为这是一个容易解决的问题的妄想的人都是如此。
3. 这可能没问题
测试有很多价值……但要适可而止。 但是,如果你可以用 10% 到 20% 的精力捕获 80% 到 90% 的错误——而且你可以——那么剩下的精力更应该用于使你的系统具有弹性,而不是防止失败。
你应该定期练习失败。 理想情况下,每个有权访问生产环境的人都知道如何进行部署和回滚,或者如何快速恢复到已知良好状态。 他们应该知道正常的操作系统是什么样的,以及如何调试基本问题。 知道如何处理失败不应该是罕见的。
如果你在生产环境中测试,处理失败 就不会是罕见的。 我说的是诸如,“这是否有内存泄漏?” 之类的事情。 也许在五台主机上以金丝雀方式运行过夜看看。 “此功能是否按计划工作?” 在某个时候,只需使用功能标志发布它,以便只有某些用户可以使用它。 诸如此类。 练习发布和修复许多小问题,而不是少数几个大的和 戏剧性的版本。
4. 你有更大的问题
你每天都在发布代码,并且经常造成自我伤害,并且你无法分辨它在之前、期间或之后在做什么。 破坏东西不是问题; 你可以安全地破坏东西。 问题在于第二部分——不知道它在做什么——这是不好的。 这个更大的问题可以通过以下方式解决
- 金丝雀发布。 自动化金丝雀发布。 具有自动升级的渐进式自动化金丝雀发布。 同时运行多个金丝雀!
- 使部署更加自动化、健壮和快速(上限为 5 分钟是好的)
- 使回滚变得非常快速和可靠
- 为分阶段的金丝雀发布使用检测、可观察性和其他早期预警信号
- 对关键端点进行端到端健康检查
- 选择良好的默认值、功能标志、开发人员工具
- 教育、分享最佳实践、标准化实践、使简单/快速的方式成为正确的方式
- 尽可能多地将代码和后端组件从关键路径中移除
- 限制任何给定用户或更改的爆炸半径
- 探索生产环境,验证预期的更改是否实际发生。 了解正常状态是什么样的
这些事情都是对你时间的极大利用。 与暂存和测试环境不同,后者 众所周知是脆弱和不稳定的,并且难以与生产环境保持同步。
做这些事情
在拥有 50 人以上的公司中,发布工程是一项系统性投资不足的技能。 你的部署几乎是你所有失败的原因,因为它们将混乱注入你的系统。 拥有生产环境的暂存副本并不能在很大程度上改变这一点(并且它增加了一大类俗称“它看起来就像生产环境,所以我只是删除了那个表……”的问题)。
拥抱失败。 混乱和失败是你的朋友。 问题不是你是否会失败,而是你何时 会失败,以及你是否会注意到。 这取决于它是让所有 用户感到恼火,因为整个站点都宕机了,还是只让少数用户感到恼火,直到你第二天早上从容地修复它。
曾经,这些都是可选的技能,甚至是专业。 现在不是了。 这些是你作为分布式系统工程师的新职业生涯中的基本要求。
全身心投入。 这可能没问题。
2 条评论