遗留系统现代化:遗留系统替换模式与实施方法


项目启动阶段,团队与对原有系统有深入了解的人员举办了一场研讨会,共同可视化现有软件架构和未来软件架构。通过这场研讨会,他们发现了一个可以利用的技术接缝:原有后端系统与集成中间件之间存在基于消息的集成。

原有后端是一个老旧的企业级 Java 应用程序,它会将“发布产品”消息放入一个由旧消息队列产品提供的队列中。在这里,“事件拦截”模式非常有用。如果将其实现为基于内容的路由,就可以控制来自原有后端的消息如何被路由,并为将消息路由到新系统创造选项。

集成中间件还会处理来自门店前端的消息,例如产品销售消息,并通过数据库连接接口直接更新遗留后端主数据库中的状态。异步消息传递与数据库更新,共同构成了遗留后端与集成中间件之间的接口。

遗留系统现代化:遗留系统替换模式与实施方法

尽管团队当时并未明确意识到,但他们实际上巧妙地在子系统层面运用了“抽象分支”模式,以替换旧版中间件。这里的抽象层就是消息队列和数据库连接接口。只要确保新的实现遵循这一抽象层,就可以在不影响业务运营的情况下替换掉“有问题的供应商组件”。

团队做的第一件事,是通过重构增加一个事件路由器,以实现事件拦截。

遗留系统现代化:遗留系统替换模式与实施方法

事件路由器的设计主要考虑了三个功能。

首先,从系统高层处理方式来看,这里使用“重构”一词,是因为系统结构发生了改变,但外部可观察行为没有变化。现在,当用户发布产品时,原有后端系统仍然会将发布消息放入旧消息队列。不同的是,集成中间件不再直接消费该消息;事件路由器会从该队列消费消息,并将其原封不动地放入另一个消息队列。随后,集成中间件从这个备用队列中消费消息。对集成中间件而言,这一改变只需要简单配置即可完成。

其次,事件路由器会将消息从一个旧消息队列取出,再入队到另一个旧消息队列。通过对配置做一些简单变更,集成中间件就能够从这个新队列消费消息。

总体而言,这次重构并没有改变系统的可观察行为,但事件路由器现在已经成为过渡架构的一部分,因为它被插入到了消息处理管道中。

事件路由器的设计愿景,是通过配置将消息路由到备用目标,从而让新的实现能够处理已发布的消息。这正是事件拦截模式的作用。

事件路由器还需要提供一座桥梁,将旧消息队列技术连接到目标架构中选定的新消息中间件技术。

事件路由的实现并非一帆风顺。由于缺乏可用的驱动程序和库,与旧消息队列集成非常困难,这一方案也曾多次受到质疑。团队清楚这一方案带来的诸多优势,最终完成了开发工作并将其发布到生产环境。他们持续监控新组件的运行状况,并计划利用新的持续交付流水线逐步增强其功能。

成功交付组件:构建功能,维护契约

遗留系统现代化:遗留系统替换模式与实施方法

新的门店前端管理器由团队迭代构建完成。在本例中,该构建包括一个主数据库适配器,用于实现“遗留系统模拟”模式。这个适配器是抽象层的一部分,用来根据从门店前端接收到的销售信息更新主数据库。

由于事件路由器并不转换消息,团队创建了一个遗留事件适配器,也就是消息转换器,用于将消息转换为新格式。这样既可以避免新系统直接暴露于遗留系统细节之下,也能符合新架构原则。

此外,团队还在新的门店前端管理器和旧版门店前端之间实现了一个旧版门店前端适配器,用于将新实现与未来门店前端替换时可能出现的变更隔离开来。

团队还在旧版门店前端上引入了一个新的 API,供新的门店前端管理器使用。同时,他们新增了一项功能,允许将通过新 API 发布产品后的回调发送到新的门店前端管理器适配器。至关重要的是,这使得旧版实现和新版实现能够并行运行。

成功交付组件:过渡到正式运行,利用第二道接缝

此时,测试新解决方案所需的条件已经具备。但问题是:如何以可控方式将它投入实际业务运行?

为此,团队利用了另一个切分点,这一次是按产品进行切分。事件路由功能得到了增强,增加了按产品类型和唯一产品 ID 进行可配置路由的能力。团队可以先测试单个产品按 ID 发布、管理和销售的流程;随后,随着时间推移,逐步配置路由,使其支持越来越多的产品类型,从而有效提高由新解决方案处理的产品比例。

当所有产品都由新系统处理后,原有集成中间件便被停用。由此,公司在许可、支持和数据中心托管费用方面节省了大量资金。

遗留系统现代化:遗留系统替换模式与实施方法

高级系统处理:除非业务另有规定,否则特定产品的处理流程与之前相同。对于业务愿意通过新系统处理的产品,处理流程如下:发布消息被放入 SwiftMQ 队列。事件路由器会检查消息有效负载并检查产品制造商。如果已配置,事件路由器会将此消息原封不动地放入 ActiveMQ 队列。旧版事件适配器会将消息转换为符合目标架构原则的业务事件。新版 Storefront Manager 应用程序会存储其自身的产品表示,并通过队列转发待发布产品的命令消息。旧版 Storefront 适配器会接收该命令,并调用旧版 Storefront 上的新 v2 API。

根据业务需要,用户现在除了管理员可以通过发出新命令来随时更改产品在店面上的展示方式外,还可以控制产品的展示方式。

当产品(通过 v2 API 发布)售出时,旧版店面会回调旧版店面适配器提供的 API,该适配器会将回调转换为业务事件,并将该事件放入 ActiveMQ 队列。新版店面管理器和主数据库适配器会使用这些事件。新版店面管理器会更新其内部产品状态,而主数据库适配器会将销售信息更新到旧版主数据库中。

改变组织结构,使这种能力能够持续运作

我们的团队此前已经与客户组织的另一个部门合作,并成功替换了另一个遗留系统。

在整个组织的工程层面,持续交付和良好的质量保障实践现在已经成为既定规范。微服务架构使容器化服务能够被定期、独立地部署到云平台上。

新的项目团队需要与新的利益相关者合作,带领业务的另一个部门踏上同样的“敏捷与持续交付”之旅。早期那些风险可控的发布,有助于赢得信任。随着时间推移,团队得以证明:包括持续交付在内的新工程实践和质量实践,如何降低那些过去常常导致官僚主义和更高治理成本的风险。因此,低频、大范围发布逐渐被更小、更频繁且置信度更高的部署所取代。当业务部门准备好接受这些变更时,团队便能够根据实际情况进行发布切换。

结语

当然,真实情况远比上述简化描述复杂得多,集成需求也更高。在生产环境中测试新方案后不久,就出现了一个需要深入系统分析的例子:一些关键业务管理信息报告中的数据不一致,部分产品信息“丢失”了。

经过大量调查,团队发现,集成中间件使用的数据库被复制到了组织的数据仓库中,而该数据库原本用于存储长时间运行的业务事务状态。通过一系列批处理作业、存储过程和视图,这些数据最终被提供给业务关键绩效指标报告使用。

遗留系统现代化:遗留系统替换模式与实施方法

为了确保这些报表不出故障,团队需要添加额外的遗留系统模拟组件。他们使用监听器监听来自门店前端的销售消息,并通过数据库连接接口将数据注入数据仓库中的相应表。这些额外的模拟组件也成为过渡架构的一部分,并将在条件允许时移除。

上述通过抽象进行分支的方法,以及相关模式和实践的使用,目的都是降低风险。

通过事件拦截这一技术切入点、遗留系统模拟以及过渡架构,客户得以将问题拆解。随后,团队又按产品这一业务切入点进行细分;在本例中,也就是按产品类型进行细分。这样一来,企业就能够以更细粒度控制更大范围的推广,并进一步管理风险。总体而言,这种方法使企业能够以自己可以接受的节奏推进系统替换。

这种方法虽然能够管控风险,但也需要付出代价。因此,需要考虑的问题是:企业究竟有多重视这种风险缓解能力?明确并量化这种重视程度,将有助于团队持续跟踪相关投资。

事件路由和遗留系统模拟都属于过渡架构投资,其目标是管理风险。它们的作用是创造更多选择,从而实现风险管理。这类工作很容易被视为“可有可无”,因此人们往往会尽量避免相关成本。正因如此,在权衡“风险缓解的价值”与“过渡架构的成本”时,务必要做到明确、透明。

常见问题

什么是遗留系统现代化?

遗留系统现代化,是指在不影响核心业务连续性的前提下,对老旧软件系统、架构、数据流和工作方式进行更新,使其能够更好地支撑业务变化、降低维护成本,并减少技术风险。

遗留系统替换一定要一次性完成吗?

不一定。对于大型企业系统而言,一次性“大爆炸式”替换通常风险较高。更可行的方式,是通过事件拦截、过渡架构、遗留系统模拟、按产品或价值流拆分等方式,逐步迁移和替换旧系统。

企业推进旧系统迁移时,最容易忽视什么?

企业最容易忽视的往往不是技术本身,而是组织结构、工作方式和业务流程。遗留系统通常与组织流程深度绑定,如果只替换技术而不调整组织协作方式,新系统很可能再次演变成新的遗留系统。

如何降低遗留系统现代化的风险?

降低风险的关键,是将大问题拆解为小问题,并通过渐进式交付验证每一步。企业可以优先寻找技术接缝和业务接缝,采用并行运行、事件路由、过渡架构和持续交付等方法,在不中断业务的情况下逐步完成系统替换。

文章包含AI辅助创作:遗留系统现代化:遗留系统替换模式与实施方法,发布者:su,转载请注明出处:https://worktile.com/kb/p/3979187

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
su的头像su

发表回复

登录后才能评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部