在许多系统中,查询和写数据有很大的不同——写数据影响的是单一的、高度规范化的实体,而查询通常是会从一系列的数据源中获取非规范化的数据。有些查询模式会受益于使用与写数据完全不同的数据存储,比如,开发者可能会使用PostgreSQL作为持久化的事务存储,但是使用Elasticsearch作为索引查询的数据存储。这种命令-查询职责分离(CQRS)模式是一种应用于这种场景的通用模型,它显式地将系统中的读(查询)和写(命令)进行分离。

1)应用的命令部分执行系统的更新操作——创建、修改和删除。命令会发出事件消息,可以是内部的事件消息,也可以是发到不同事件总线上的事件,如RabbitMQ或Kafka。
2)事件处理器消费这些事件,以构建合适的查询或者读模型。
3)系统的“命令”和“查询”这两部分分别由不同的数据存储来提供支持。
我们可以在服务内部应用这种模式,也可以在整个应用层面应用这种模式。可以使用事件消息来构建一些专门的查询服务,让这些服务维护一些应用层面的复合型的数据视图。比如,假设需要汇总所有账户的订单手续费,并且要按照不同的属性(如订单类型、资产类别、支付方式)进行分类汇总。仅仅在单个服务层面是不可能完成这个功能的,因为不管是fee服务、order服务还是customer服务,它们都不拥有全量的数据来支持按照那些属性过滤,每个服务只有一部分数据。

如图,构建一个CustomerOrder的查询服务来组织对应的数据视图。在不确定这些数据视图属于哪个服务时,单独维护一个查询服务是很有效的办法,这样能够确保对关注点合理地划分。
在微服务应用中,CQRS有两大核心优势:第一,可以针对特定的查询请求优化其查询模型来提升它们的性能,并消除了对跨服务的join关联的需要;第二,有助于在服务和整体应用层面实现关注点分离。
那么CQRS有没有劣势呢?
当然事物都有两面性,后续了解CQRS的劣势。
摘取自 摩根·布鲁斯和保罗·A.佩雷拉的《微服务实战》
网友评论