CQRS命令查询职责分离

背景

        在开发一个业务功能时,一般对该业务模型进行命令和查询操作,命令负责对数据进行修改和更新,而查询负责对数据进行读取和查询。当命令操作的所需数据模型和查询的所需数据模型相差很大,不管如何统一数据模型,都需要在业务逻辑中进行复杂的调整,来适配命令和查询操作业务模型。如果这种适配太复杂、成本高、可维护性差,或查询操作性能不够,还不如把命令和查询分离,命令操作有自己的数据模型和相关业务逻辑, 查询也有自己的数据模型和业务逻辑,维护各自的领域反而成本更低、可维护性更好,设计上也更加高内聚低耦合,部署时可以根据自己并发量进行合适缩放。这种命令和查询分离设计的模式就称为 CQRS。

CQRS 实现方案

        CQRS 的实现中,命令操作业务和查询业务有各自限界上下文和领域模型,各自数据存储技术方案独自选型,独立存储,一般命令操作需要关系型数据的强事务,而查询操作更多的读操作因此会选择查询性能更高 nosql 数据库,或者通过 redis 缓存提高查询性能,查询数据存储结构需要更符合查询显示的所需的结构。 多个查询业务差距较为明显时,把这些查询业务也都隔离,单独设计合适自己的领域模型和存储结构。命令操作的更新,需要把数据更新到查询领域的模块中,一般情况下采用异步更新,通过消息队列发布订阅。不过异步,需要注意幂等和事件顺序,否则会导致查询结果错误。要求更高的,可以采用经常配套的事件溯源的设计模式,在性能、可靠性、灵活性和可追溯性上更好,不过实现起来也更加复杂。 异步查询有一定的延时,如果一些场景需要命令操作后,马上就要查询显示更新的最新数据,那么命令模块和查询模块的数据更新应当采用同步方法,通过命令操作模块调用查询模块的接口更新后才代表命令操作完成,不过这样命令操作的延时性会增加。

适合的场景

        1, 业务逻辑复杂,命令操作和业务查询的数据模块差异较大,从而一个业务模块专注于复杂模型的写入,另一个业务模块专注于高并发的读取模型和服务用户界面,随着系统发展,各自进行模块演进和版本变更。

        2, 查询多,性能要求高,命令操作的写频率一般。为了提高查询性能,并根据访问量扩充更多查询服务实例, 写和读两者选择技术实现方案差距很大,无法采用同一种数据库,此时读写分离更为合适,也就是 CQRS。

不适合的场景

        1,业务规则简单,可以通过单一数据存储结构,通过上层简单调整,来适配不同查询和命令操作。

        2, 简单的 CRUD 样式用户界面和数据访问操作就足够了。

总结

        总之,CQRS模式可以提高应用程序的可扩展性、可维护性和性能,但它的实现成本也很高,命令和查询的数据同步方案往往较为复杂,而且有的需要处理事件顺序和重复消息,因此,需要做好场景分析和成本估算后,谨慎选择 CQRS 的设计架构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值