微服务模式:Semver自动部署

使用语义版本控制来保持控制,同时将微服务无缝部署到生产中

谁控制什么?

在采用微服务架构时,赋予服务所有者自治是主要目标之一。 开发人员应在不依赖其他服务的情况下,以自己的步调改进和操作他们的服务。

但是,整个产品包含许多微服务-它们都必须协同工作才能为用户提供适当的体验。 因此,将有诸如事件总线之类的共享基础结构来连接服务。 反过来,将有一个运维/基础架构团队维护共享的基础架构并为服务团队提供指导。

很快出现了一个问题:服务开发人员应该对部署进行多少控制,Ops团队何时应参与其中?

极端答案

让我们考虑一下如何处理部署的两种极端情况:

  • 运营团队门票 :服务开发人员创建一个新版本,然后要求运营团队将其部署到生产环境中
  • 持续部署 :服务开发人员推送新代码,CI系统构建新版本并自动将其部署到生产中

我们发现两种方法都有问题。 要求Ops团队进行部署肯定可以追溯到6个月的发布周期:开发人员不愿意提出要求,Ops不愿意执行单调的任务-每个人都非常愿意尽可能少地进行部署。 所以,这是不行的。

更有趣的是,连续部署也存在问题:

  • 持续部署需要训练有素的开发人员(例如,审查流程)和成熟的代码库(例如,广泛的自动化测试),以防止将损坏的代码推广到生产中。
  • 有时,将所有承诺投入生产并不是一个好主意。 例如,由于对Web应用程序进行了修饰性的提交,我们不想释放浏览器缓存。
  • 协调的部署变得非常困难,例如,如果API更改需要同步部署两个服务。 当变更影响基础架构时,这尤其具有挑战性-Ops肯定希望参与其中。

那么,在这两个极端之间是否有可行的方法?

通过Semver发出影响信号

我们最终解决了一个折衷方案,即a)让服务团队控制何时部署的内容,以及b)在重要时让Ops团队参与。

首先,我们自动部署到生产环境,但仅部署了标记版本。 这意味着服务开发人员可以控制部署的内容,而无需任何手动部署工作。

其次,我们使用语义版本控制来发出新版本的预期影响。 语义版本是根据更改的严重性分配版本号的一种做法。 例如,与v1.0.0相比, v1.0.1仅具有很小的补丁; v1.1.0将具有v1.0.0新功能; 而v2.0.0将包含重大更改。

语义版本控制的优点在于,它消除了编写冗长的变更描述的需要,而Ops团队则必须根据该描述来猜测潜在的影响。 而是,服务开发人员以一种广泛使用的,机器可理解的格式( v1.0.1 )给出对变更影响的估计。

自动处理可预测的变更,协作进行风险变更

在使用寿命开始时,团队与Ops团队达成共识,应自动部署哪种发行版:仅补丁发行版,还是所有次要发行版。 根据定义,推送新的主要版本始终需要Ops参与。 基于此讨论,Ops设置了自动部署规则,例如v0.xx自动部署所有修补程序和次要版本。

这是开发过程中发生的事情:对于一个小的修复程序,开发人员创建一个补丁标签,并且我们的部署系统自动将新版本部署到生产中。

开发人员可以将主要版本部署到集成环境中进行测试。 然后他们打开Ops的票证,描述应如何更新自动部署版本(例如,从v2.xxv2.xx )以及更改内容(允许Ops自己进行影响评估)。 票证还可以请求与另一个服务进行同步更新(例如,将service-A从v2.xx升级到v1.xxv2.xx service-B从v3.1.xv.3.2.x )。

陷阱和学习

我们使用基于semver的自动部署已超过2年。 它为开发人员带来了更高的速度,减少了Ops的重复工作,从而消除了开发人员与Ops之间的诸多挫败感。

在此过程中,我们吸取了两个重要的教训:

  • 开发人员必须真正理解语义版本。 特别是,他们需要内部化“版本号便宜”。 如有疑问,请使其为次要版本,而不是补丁程序版本。
    简而言之,看到v8.42.231版本会让我们感到轻松— v1.0.1是危险信号。
  • 目的绝不是要避免开发人员和Ops之间的沟通。 相反,我们只想摆脱Ops无法添加任何有价值的令人沮丧的对话。
    我们将节省的时间投入到有关困难案件的更深入的对话中。 特别是当新版本可能影响基础架构时:Ops是开发人员最好的朋友,可以顺利地将其部署到生产中。

编码愉快!