此模式是 "遗留置换模式" 的一部分

过渡架构

安装的软件元素,以简化遗留系统的置换,我们打算在置换完成后将其删除。

2022 年 3 月 28 日

Ian CartwrightRob HornJames Lewis

遗留置换成功的核心是逐步用新软件替换遗留软件,因为这允许尽早交付收益并规避大爆炸的风险。在置换期间,遗留系统和新系统将不得不同时运行,允许行为在旧系统和新系统之间进行拆分。此外,随着遗留系统的逐渐消失,这两个系统之间的分工也会定期发生变化。

为了允许遗留系统和新系统之间的这种相互作用,我们需要构建和演进过渡架构,以支持这种协作,因为它会随着时间的推移而发生变化。中间配置可能需要在目标架构中没有位置的集成。

或者更直接地说 - 你不得不投资于将被丢弃的工作。

工作原理

考虑一下建筑物的翻新。建筑师已经为你提供了完工产品的渲染图,建筑工人也已准备就绪开始工作。但第一步是在建筑工地上搭设脚手架。

雇用脚手架本身并支付团队搭建脚手架的费用是一项不可避免的投资。它需要启用关键工作的完成,并在翻新期间购买风险缓解,从而提高工人的安全性。它甚至可以解锁新的选项 - 允许你在更换屋顶时修复烟囱或处理悬垂的树木(为了进一步扩展比喻)。一旦工作完成,另一个团队将到达并拆除脚手架,你会很高兴看到它消失。

在遗留置换的背景下,这种脚手架由软件组件组成,这些组件简化或启用构建当前向目标架构演进的步骤。与脚手架一样,这些软件组件在达到目标架构后就不再需要,必须将其删除。

一次性替换大型遗留单体系统存在风险,我们可以通过分多个步骤进行置换来提高业务安全性。我们可以通过功能子集或数据子集来实现这一点,使用诸如 提取价值流提取产品线 之类的模式。要执行任何这些操作,我们需要拆分单体系统,这需要在单体系统中引入接缝以分离其各个部分。引入单体系统接缝的组件是过渡架构,因为它们在单体系统被置换后必然会消失,它们也不需要单体系统来履行其现有职责。

我们可以通过查看单体系统的不同部分如何相互通信,并在通信路径中放置一个组件来引入接缝,我们修改该组件以将流量转移或复制到其他元素。 事件拦截 通过事件进行通信,通过抽象分支 通过 API 进行通信。当我们创建这些接缝时,我们可以引入 遗留模拟 以将新组件引入遗留通信流。

遗留置换中最大的挑战之一是处理数据,遗留系统通常直接访问数据。如果可能,明智的做法是通过引入 API 来引入接缝,以替换直接数据访问 - 例如采用 存储库 模式。但是,当我们无法做到这一点时,我们需要复制系统的状态。 遗留模拟事件拦截 在我们需要走这条路时都很有用。

通常用作过渡架构的模式
使用模式
创建接缝

事件拦截

遗留模拟

通过抽象分支

存储库

反腐败层

复制状态:新 ➔ 旧
(“保持灯火通明”)

遗留模拟(服务消费模拟)

复制状态:旧 ➔ 新

遗留模拟(服务提供模拟)

事件拦截

即使心中有明确的目标架构,也有许多途径可以到达那里。团队可以采取的每条不同路径都需要或需要不同的过渡架构来实施。在这种情况下,我们需要对每条路径进行成本/效益分析,以足够详细的程度,以便我们可以看到它是否对选择产生影响。

请记住,使用过渡架构的一部分是在不再需要时将其删除。在构建它时,可能值得多投资一点,以添加一些功能,使其以后更容易删除。同样,我们需要确保它被正确删除 - 不必要的组件,即使未使用,也会使未来的团队维护和演进系统的工作变得复杂。

何时使用

没有人喜欢浪费辛苦工作,当我们谈论构建我们打算丢弃的东西时,这种情绪自然会产生。很容易得出结论,可丢弃的东西没有价值。但过渡架构以多种方式提供价值,这种价值应该与构建它的成本进行比较。

第一个价值是它通常可以提高向企业交付功能的速度。这里一个方便的比喻是在粉刷墙壁时使用油漆工胶带覆盖装饰条。如果不贴装饰条,你必须在装饰条附近仔细缓慢地粉刷。在粉刷之前放置胶带,并在粉刷之后将其移除的成本,可以通过提高速度(以及降低技能)来弥补,从而避免将油漆涂到错误的地方。

这种软件中的权衡被时间价值的重要性放大了。如果企业需要一个新的仪表板,该仪表板将被置换的遗留系统中的现有数据与新系统中的数据集成,你可以通过在新的仪表板中构建一个网关来更快地实现这一点,该网关读取并转换遗留来源的数据,使其成为仪表板所需的格式。一旦遗留系统被移除,这个网关将被丢弃,但拥有一个集成仪表板的价值,在替换发生之前的时间内,可能远远超过创建它的成本。如果比较接近,我们还应该考虑遗留替换比预期花费更长时间的可能性。

过渡架构的第二个价值是它如何降低遗留置换的风险。在客户管理系统中添加 事件拦截 会花费一些构建成本,但一旦构建,它就可以逐步迁移客户(例如使用 提取产品线提取价值流)。迁移一部分客户可以降低迁移过程中出现严重错误的可能性,并倾向于降低任何出现问题的后果。此外,如果出现非常严重的问题,事件拦截 可以轻松地恢复到以前的状态。

作为一项规则,团队在遗留置换期间应始终考虑过渡架构,并集思广益,找出构建一些临时软件可以实现这些好处的方法。然后,团队应评估提高时间价值和降低风险的好处与构建这种短暂软件的成本。我们认为,许多人会惊讶于临时软件在多长时间内收回成本。

示例:架构演变

本节探讨了概述文章中介绍的中间件移除示例,并描述了过渡架构如何实现系统的安全演进。

遗留配置

如概述中所述,现状架构包括主要遗留系统,该系统负责定价并将产品发布到遗留店面,通过一些集成中间件。该中间件从遗留队列中消费产品发布事件,并处理产品在店面上的展示方式的长时间运行的编排。当产品售出时,遗留店面会调用中间件,该中间件会更新底层共享遗留数据库中的产品状态。遗留中间件还将内部状态存储在遗留数据库中,该数据库通过数据仓库提供给关键报告。请参阅 关键聚合器

目标架构

在目标架构中,遗留店面仍然存在,但它的一些职责已移至新的店面管理器组件中。店面管理器将消费资产处置路由器在产品被路由到该渠道出售时产生的业务事件,并将使用新的 API 将产品发布到店面。店面管理器将负责产品在店面中的显示方式。当产品售出时,遗留店面会使用新的 API 调用店面管理器,然后店面管理器会发出一个业务事件,供下游资产销售处理组件消费。

第一个小的启用步骤

要添加的第一个过渡架构是事件路由器组件。这是 事件拦截 模式的示例。事件路由器创建了一个可以利用的技术接缝,以通过新组件路由待售产品。

引入店面管理器

下一步是添加新的店面管理器。这里也添加了过渡架构,它服务于两个截然不同的目的。即隔离新组件与遗留问题(例如数据结构和消息),以及在遗留世界中保持灯火通明。为了隔离(反腐败层),创建了一个事件转换器,将事件路由器路由的遗留消息转换为新的干净的业务事件格式,供店面管理器消费,并且该格式将在目标架构中持续存在。店面管理器和遗留店面将通过新的 API 协作,因此添加了此 API,以及内部 事件拦截,以便当产品售出时,遗留店面会“回调”到发布该产品的系统。为了保持灯火通明,需要两个过渡架构。首先,当产品售出时,会发布新的业务事件。这些事件被一个临时遗留数据库适配器消费,该适配器模拟集成中间件,使用销售信息更新遗留数据库。其次,创建了 MI 数据模拟。它既是事件拦截器,又是遗留模拟 - 它拦截新 API 中的事件,并使用业务关键报告所需的“状态”信息更新遗留数据库。

业务成果 - 遗留中间件的停用

遗留系统仍然负责确定哪些资产可以出售,以及发送产品以供发布,但随着时间的推移,路由到新组件的产品数量不断增加(请参阅 提取产品线),直到 100% 的流量都在处理,而无需依赖遗留中间件。此时,可以停用遗留中间件,将新的店面管理器和过渡架构组件保留在生产环境中。

引入资产处置路由器

一段时间后,新的资产处置路由器组件上线。(请记住,这个例子是简化的,来自一个更大的遗留系统迁移项目的经验。)该组件发布了新的商业事件,用于产品,可以被店面管理器消费。不再需要事件路由器,因为其他组件已经接管了确定哪些资产需要处置的任务,也不需要事件转换器 - 所以这些组件可以被停用。由于遗留中间件已被停用,业务关键报告已更改为使用新组件的数据(参见 恢复到源),因此 MI 数据模拟组件也可以被停用。

安全抵达目标架构

一段时间后,新的资产销售处理组件上线,它接管了遗留系统中的最后一组职责(在本例的范围内)。此时,过渡架构的最后一个组件,遗留数据库适配器,可以被移除。店面管理器产生的商业事件被资产销售处理组件消费。

重大修订

2022 年 3 月 28 日: 首次发布