architecture - 使用 CQRS 改进传统的单体系统
问题描述
我正在研究一个关键的遗留系统,它的数据模型有改变的风险。该系统的工作负载由相当少的写入和大量读取组成。
现在,我需要向一些客户端公开一些新的 API。要实现这些 API,我需要创建新记录或合并旧系统中的多个记录。
考虑到与更改遗留系统相关的风险,以及新 API 所需数据的复杂性,我的一个解决方案是使用报告数据库。
另一种可能的解决方案是使用类似 CQRS 的架构,以便旧系统继续使用自己的数据模型(命令部分)存储数据,并使用消息代理将任何更改(事件)传递给另一个系统,该系统存储数据以适合客户端查询的方式(查询部分)。因为这个系统总体上是单体的,所以我的事件只能包含更改实体的标识符,而查询部分可以通过直接查询遗留系统的共享数据库来检索完整记录。
我知道与 CQRS 架构相关的复杂性,特别是在分布式系统中。在纸面上,它似乎解决了很多困难,包括修改遗留系统。但是我仍然不确定使用 CQRS 来解决我描述的问题是否是一个好主意,因为有些人认为 CQRS 应该只用于新建项目。
任何建议将不胜感激。
解决方案
CQRS 绝对不仅仅适用于新领域。将大型遗留系统转换为 CQRS 可以成功完成,只是需要一点技巧和时间。
关键是在尝试构建报告端之前将事件管理注入遗留系统。理想情况下,您在遗留系统中有一个存储库方法,您可以在其中将写入添加到事件中心。这些事件写入将是即发即弃的异步,因此它们会给遗留系统所在的服务器增加一点负载,但不应影响单个写入的响应率。如果您没有适当的存储库模式,那么现在可能是重构的时候了。如果您没有存储库并且不想重构其中一个,那么一种不愉快的可能性是向数据库添加触发器以写出事件。
在注入事件创建逻辑的同时,您还可以设计报告端。在大多数事件逻辑出现之前,我不会开始构建报告端,因为您会反复从旧系统中发现您没有计划的新事件。当您意识到您需要这些新事件时,您的报告方面的计划将会改变,如果您已经部分构建了它,您最终可能会丢弃刚刚编写的代码。
一旦事件到位,只需敲出代码以支持读取端,这很费力但微不足道。
一定要给自己足够的时间来做这件事。无论您计划多少,在此过程中都会有很多试验和错误,所以它肯定会花费您比您想象的更长的时间。如果截止日期很紧,复制到报告数据库可以更快、更便宜地完成工作,但它的灵活性会降低,并且需要更多的维护。
令人惊讶的是,一旦它们到位,事件会有多么有用。事件侦听器开始出现在您不会想到的各种不同的系统中,因此,如果您可以让管理层接受事件处理方法的更高成本和更长的时间线,它就会得到回报。
推荐阅读
- audio - 填充音频缓冲区时的降噪
- c# - 无法从服务器向客户端发送 TCP 消息(使用 c# tcp 侦听器)
- kotlin - Kotlin - IllegalArgumentException
- json - 在 Powershell 中输入 JSON 数据
- wicket - 带有 Rest 服务的 Wicket 和 ajax
- functional-programming - 将函数定义为 codomain 的子集
- css - 我可以让 div 像按钮一样缩小到文本宽度吗?
- node.js - 如何设置本地 AWS Secrets Manager Docker 容器以进行本地测试?
- python - 访问 SharePoint 导致文件损坏
- excel - 如何从工作表中提取公式并在前面添加“=”以运行