在以前的工作中,我们过去常常通过执行热代码加载来部署实时系统。我们有一件事可以自动将所有新代码推送到每个服务器的磁盘上,但不会对其执行任何操作。然后,工程师将登录到REPL中的一个Erlang节点。所有Erlang节点始终连接在一个网格中,因此其中一个节点可以与任何其他节点通信。
对于每个部署,在REPL中都会有一个可以复制/粘贴的小脚本,其中所有的构建步骤都在开发中尝试过,然后是一个提前准备的环境。我们从一个小模板开始,它有4个功能:
UpgradeNode()%Upgrade当前节点;返回确定或错误NodeVersions()%返回所有运行节点的版本NodesAt(VSN[,count])%返回给定版本的所有或计数节点的名称RollingUpgrade(Nodes)%滚动升级列表中的节点。
您可以将脚本复制粘贴到您所在的生产实例上,调用UpgradeNode(),看看它是否工作,然后调用RollingUpgrade(...)。如你所认为的那样积极或谨慎。如果您愿意,可以在几毫秒内实时部署数十个或数百个实例,而不会丢失一个连接。如果你愿意,你可以慢慢来,分阶段进行,仔细地监控事情。
我们将要部署的系统每秒可以处理超过1亿条消息。它在任何给定的时间都由一个或两个开发人员维护和操作,我们可以在任何时候部署它,甚至没有人从任何操作度量中意识到这一点。它真的很整洁,而且很有说服力。
如果我们需要(或者如果我们对给定的实时升级的安全性不太有信心),该系统可以分阶段缓慢运行,因为我们仍在运行不变的基础设施。但这是可选的,我们可以自由地分解我们的变更集,以便可以安全地实时部署更多变更集。它在设计代码时创造了新的可能性。
它最终被GO实践正常化的多次尝试所推倒,无论何时涉及到开发周期的操作方面,基本上都让您独自一人,然后集装箱化接管了工作,整个管道都失去了做好的有状态的事情的方法,这为每个人节省了数小时的部署时间,并在州损失的情况下节省了排水和重新连接风暴。
在另一项工作中,我们花了大约3个月的时间来确定和实施嵌入式监控设备(如机场的摄像头)签名包的就地升级,这样您就可以在不需要关闭整个基础设施和中断实时安全的情况下对生产设备进行更新。任何失败实际上都会自动崩溃并回滚到当前版本(以毫秒为单位),除非我们将磁盘上的文件标记为新版本是可接受的。它甚至有一个很小的管理面板,在那里你可以对每台设备的所有版本进行实时升级,并在不中断任何数据流的情况下看到情况的变化。
这也被取消了;Docker被视为更容易处理整个云部分的事情,现在没有人能真正部署它。产品要求进行了更改,以适应采用的技术。在大多数情况下,计划内停机或多或少成为一种必要,因为在关键系统中推出产品时,您承担不起空出安全覆盖范围的后果。
这些工具仍然存在,但它们不再被视为几乎在任何地方都可以采用的良好做法。我仍然对现代DevOps整个变态的码头遇上库伯内斯(Kubernetes)强制不变的生态系统感到不满,因为它每次都急切地把洗澡水扔给婴儿。一成不变的基础设施很好,但就其本身而言,也相当平淡无奇。我们现在感受到了网络效应,因为选择不再真正存在,因为一切都假设你应该一直是无国籍的。
还有一种广泛的误解,认为Kubernetes(或任何其他集群调度器)取代了Erlang/OTP中的监督树的概念。事实是,它们在不同的范围内运作。只需让它崩溃并重新启动";,因为Erlang通常在请求级别工作,有时甚至在更细的粒度上工作。您仍然可以从群集级别的控制平面中获益,但是如果您可以两者兼得,您会得到更丰富的东西。问题是,除非你两个都试过了,否则你不会真正对什么是可能的有一个很好的概念,而且很容易被锁在盒子里思考。
对我来说,放弃所有这些实时升级,只使用K8,就像有人要求我在每次出现小问题时都删除所有错误和异常处理并重新启动计算机。能够做到这一点肯定有一个有用的方面,但失去在更精细的粒度上工作的能力是一个巨大的损失。
让它崩溃并重新启动的问题是,它是一个很好的默认支持机制,可以应对您的失败。这就是你开始的地方,如果你让这种情况可以接受,那么你的情况总是可以控制的。这真的很棒。关于Erlang和Elixir,不言而喻的是,从那时起,您的系统就是一个活生生的东西,您可以通过调整监督树的结构,或者通过逐步处理越来越多的边缘案例(如果您知道如何处理它们的话)来优化它们。
无状态容器和Kubernetes所做的事情是,当一件事情出错时,处理它的基本情况,替换它并恢复到良好状态。";它不容易让您做的事情是";,然后开始迭代,以便越来越好地不丢失所有状态并快速恢复。我们的想法是,您应该能够插入不变量,并且在情况不好的情况下仍然可以摆脱困境,但也可以选择在事情运行正常时保持运行:不需要预热缓存,不需要处理同步,不需要重新协商会话,不需要重新实例化,需要处理的功能标志更少,而且几乎是即时部署,而不是花费很长时间。
我们正在将自己与一整类有价值的优化隔离开来,这些优化是构建我们的工作流、概念化软件和配置更改的方法。
不可变的基础设施接受后盾,并迫使每个人只使用后盾。它永远在你遇到的每一个红灯的街角都使用安全气囊。