1.概念

CQRS全称:Command Query Responsibility Segregation ,中文名:命令查询与职责分离

2.什么是CQRS

CQRS 将系统中的操作分为两类,即「命令」(Command) 与「查询」(Query)。命令则是对会引起数据发生变化操作的总称,即我们常说的新增,更新,删除这些操作,都是命令。而查询则和字面意思一样,即不会对数据产生变化的操作,只是按照某些条件查找数据。

CQRS 的核心思想是将这两类不同的操作进行分离,然后在两个独立的「服务」中实现。这里的「服务」一般是指两个独立部署的应用。在某些特殊情况下,也可以部署在同一个应用内的不同接口上。

Command 与 Query 对应的数据源也应该是互相独立的,即更新操作在一个数据源,而查询操作在另一个数据源上

3.CQRS架构

先看一下 CQRS 的架构图:

从图上可以看到,当 command 系统完成数据更新的操作后,会通过「领域事件」的方式通知 query 系统。query 系统在接受到事件之后更新自己的数据源。所有的查询操作都通过 query 系统暴露的接口完成。

从架构图上来看,CQRS 的实现似乎并不难,许多开发者觉得无非是「增删改」一套系统一个数据库,「查询」一个系统一个数据库而已,有点类似「读写分离」,并没有什么特别的地方。但是真正要使用 CQRS 是有许多问题与细节要解决的。

4.CQRS带来的问题

事务

在原本单一进程,单一数据源的系统中,依靠关系型数据库的事务特性能够很好的保证数据的完整性。但是在 CQRS 中这一切都发生了变化。

当 command 端完成数据更新后,需要通过事件的形式通知 query 端系统,这就存在着一定的时间差,如果你的业务对于数据完整的实时性非常高,那么可能 CQRS 不一定适合你。

其次一个 command 触发的事件在 query 端可能需要更新数个数据模型,而这也是有可能失败的。一旦更新失败那么数据就会长时间的处于不一致状态,需要外部的介入。这也是在使用 CQRS 之前就需要考虑的。

从事务的角度来看 CQRS,需要面对的是问题从根本来说是个最终一致性的问题。

查询模型的设计

虽然 CQRS 为我们分离了领域模型和服务于查询功能的数据模型,但这意味着我们需要设计另一套针对查询功能的数据模型。一般比较简单的做法是按照查询功能所需的数据进行设计,即针对每一个查询接口设计一个数据视图,当收到领域事件时更新有关联的数据视图。

但是这种简单做法带来的问题就是当查询接口越来越多时就会难以管理,仍然需要按照 DDD 中划分 领域 的思路将属于一个 领域 的查询集中管理作为整个查询系统的一个上下文,或是干脆独立出来做一个微服务。所以即使引入了 CQRS,我们依然需要使用领域驱动的思路设计查询接口。

5.总结

CQRS 在 DDD 中是一种常常被提及的模式,它的用途在于将领域模型与查询功能进行分离,让一些复杂的查询摆脱领域模型的限制,以更为简单的 DTO 形式展现查询结果。同时分离了不同的数据存储结构,让开发者按照查询的功能与要求更加自由的选择数据存储引擎。

同样的,CQRS 在带来架构自由与便利的同时也不可避免的引入了额外的复杂性与技能要求,例如对于分布式事务,消息中间件的管理,数据模型的设计等等,所以在引入 CQRS 之前需要对团队能力与现有架构做仔细的分析,对短板进行必要的提升。如果现有系统逻辑较为简单,只是一些 CRUD,那么并不建议使用 CQRS。但是如果你的业务系统已经非常庞大,业务流程庞杂,逻辑繁琐,那么不妨尝试使用 CQRS 将 Command 与 Query 进行拆分,将领域模型与数据模型的边界划分的更清晰些。

领域驱动设计之CQRS相关推荐

  1. 一文看懂 DDD(领域驱动设计)、CQRS和Event Souring与分层架构

    我最近开始学习领域驱动设计,CQRS和事件溯源. 到目前为止,我主要参与了使用"经典"N层/层架构和关系数据库的项目. 随着项目变得越来越复杂,我注意到这个模型并不总是很好. 不久 ...

  2. 领域驱动设计和CQRS落地

    目录 1. 前言 2. 领域驱动架构2.1 分层架构2.2 DIP改进分层架构2.3 六边形架构2.4 洋葱架构.整洁架构 3. 领域驱动模式3.1 SIDE-EFFECT-FREE3.2 CQRS ...

  3. 领域驱动设计的实践 – CQRS Event Sourcing

    1.前言 领域驱动(Domain – Driven Design)设计的理念在于建立一系列既符合软件所处领域本身又适合软件分析开发需要的领域模型.命令查询与职责分离(Command Query Res ...

  4. [理论]领域驱动设计 DDD 是啥,cqrs是啥

    父文章 如何成为一名架构师,架构师成长之路_个人渣记录仅为自己搜索用的博客-CSDN博客_架构师成长之路 [落地版]领域驱动落地 [理论版]领域驱动设计DDD 代码框架 · 语雀 子文章 如何写可维护 ...

  5. 领域驱动设计DDD和CQRS落地

    DDD分层架构 Evans在它的<领域驱动设计:软件核心复杂性应对之道>书中推荐采用分层架构去实现领域驱动设计: image 其实这种分层架构我们早已驾轻就熟,MVC模式就是我们所熟知的一 ...

  6. 一文理解 DDD 领域驱动设计!

    来源丨SpringForAll社区 2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity in the Heart of Softwa ...

  7. DDD领域驱动设计基本理论知识总结

    领域驱动设计之领域模型 加一个导航,关于如何设计聚合的详细思考,见这篇文章. 2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity i ...

  8. 领域驱动设计(DDD:Domain-Driven Design)

    领域驱动设计(DDD:Domain-Driven Design) Eric Evans的"Domain-Driven Design领域驱动设计"简称DDD,Evans DDD是一套 ...

  9. 领域驱动设计系列文章汇总

    Entity Framework之领域驱动设计实践 EntityFramework之领域驱动设计实践 - 前言 EntityFramework之领域驱动设计实践 (一):从DataTable到Enti ...

最新文章

  1. 【他们都说 select * 不好,但是 。。。】
  2. 大学计算机实验教程实验报告2.2,大学计算机实验2-实验报告.pdf
  3. 北大阿里中科院提出细粒度人体姿态迁移方法,提升外观细节逼真度
  4. 使用Powershell远程管理Windows Server(WinRM)
  5. HBase之HRegionServer处理put请求
  6. SublimeText3 插件的使用和本身的配置
  7. 2020年——1024
  8. 自定义tableView的section header/footerView时的view复用问题
  9. ghost64怎么装linux,CentOS 7.5上安装Node.js搭建Ghost个人博客
  10. Spring源码下载并导入Idea
  11. 《流畅的python》概述
  12. 一起学ORBSLAM2(6)ORBSLAM中的特征匹配
  13. dede添加文章php,DEDE伪原创插件 一键导入1.5万替换词数据
  14. Python根据拼音对中文排序
  15. 饭饭科普46 — 为什么出现区块链
  16. 遇到问题--mongodb--Prematurely reached end of stream
  17. 电脑显示未连接一个服务器怎么处理,Win7开机提示“未能连接一个windows服务”的解决方法...
  18. 初学者在VMware上搭建自己的CentOS8
  19. Android——腾讯QQ的Tab按钮动画效果完美实现
  20. java 通过 冰蓝 word 转pdf ,最大程度包装pdf 样式和word接近

热门文章

  1. 01、RN 系列之 什么是 ReactNative
  2. C++的Dll来实现IceBox的服务
  3. R语言 tidyverse系列学习笔记(系列1)基础功能的代码实现
  4. 房地产数字化转型方案:全方位数智化系统运营,助力房企管控实效提升
  5. Qt5.8《网络版够级游戏》编写日志之一:整体规划
  6. matlab手写数字识别图片集下载,Matlab实现Mnist-image 手写数字图像识别
  7. VS2005在Win7上兼容性问题解决
  8. Python全栈工程师特训班-第一期直播回放-韦玮-专题视频课程
  9. QGIS测试瓦片下载
  10. snm算法_基于SNM算法的大数据量中文商品清洗方法