在功能迁移过程中对其修改
贯穿全书,我将重点介绍我专门选择的模式,因为这些模式可用于把现有系统增量迁移到微服务架构。增量迁移的主要原因之一是,他使我们可以把迁移工作与正在进行的功能交付整合在一起。但是,当我们想要在迁移系统时修改或丰富系统行为时,仍然会存在问题。
例如,想象一下,我们将使用绞杀者模式把现有的Payroll功能从单体中迁移出来。绞杀者模式允许我们将迁移过程划分为多个步骤,并且理论上,我们可以在任何一个阶段回滚迁移操作。如果我们向用户推出了新的Payroll服务,并发现该新服务存在问题,则可以把对Payroll功能的调用迁移回老的系统。如果单体和微服务的Payroll功能是一致的,这种方式是非常好的。但是,如果我们在Payroll的迁移过程中修改了Payroll的功能呢?
如果在新的Payroll微服务上修复了少量的bug,但是没有在单体中实施同样的工作,那么回滚也将导致这些错误再次出现在系统中。如果Payroll的微服务增加了新功能,则会带来更大的问题——回滚意味着用户将无法使用该新增的功能。
没有简单的方法可以解决这种问题。如果想要在迁移完成之前修改功能,那么就必须接受回滚会更加困难这一事实。如果不允许在迁移完成之前进行任何更改,则事情会变得更容易。迁移花费的时间越长,对系统的这一部分实施“功能冻结”(feature freeze)就越难——只要有一个需求需要修改系统的一部分,则这种需求就不可能消失。完成迁移所需的时间越长,对于“仅在迁移到该功能时将该功能实现就好”译注1的观点所承受的压力就越大。每次迁移的规模越小,在迁移完成之前修改待迁移功能的压力就越小。
迁移功能时,尽量消除对待迁移功能的任何更改——尽可能把新功能或Bug修复推迟到迁移完成之后。否则,可能会降低系统的可回滚能力。
译注1. 原文为:just slip this feature in while you’re at it. ↩