内容总结自《微服务架构设计模式》
在微服务架构中实现查询
- 一、使用API组合模式查询
- 1、简介
- 2、设计形式
- 3、弊端
- 二、使用CQRS进行查询
- 1、简介
- 2、利弊
- 三、CQRS架构
- 1、设计
- 2、存储
- 3、数据访问模块
- 四、总结
一、使用API组合模式查询
1、简介
这是最简单的方法,应尽可能使用。它的工作原理是让拥有数据的服务的客户端负责调用服务,并组合服务返回的查询结果,实现从多个服务检索数据的查询。
2、设计形式
选择由谁来扮演查询操作的API组合器这个角色,通常有三种选择。这里可以类比设计模式中的门面模式
方式一:
方式二:
方式三:
3、弊端
1、增加了额外的开销
它需要调用多个服务和查询多个数据库,这带来了额外的开销。在单体应用程序中,客户端可以使用单个请求检索数据,这通常会执行单个数据库查询。相比之下,使用API组合模式会涉及多个请求和多个数据库查询。因此,它需要更多计算和网络资源,运行应用程序的成本也相应增加。
2、可用性降低
操作的可用性随着所涉及的服务数量而下降。因为查询操作的实现涉及多个服务:API组合器和至少两个提供方服务,其可用性将显著小于单个服务的可用性。例如,如果单个服务的可用性为99.5%,则调用四个提供方服务的findOrder ()接口的可用性为99.5%(4+1)=97.5% !
3、缺乏事务数据一致性
单体应用程序通常使用一个数据库事务执行查询操作。ACID事务受制于隔离级别的约束,可以确保应用程序具有一致的数据视图,即使它执行多个数据库查询。相反,API组合模式则是针对多个数据库执行查询。这种方式存在一种风险,即查询操作将返回不一致的数据。
二、使用CQRS进行查询
命令查询职责隔离模式它比API组合模式更强大,但也更复杂。它维护一个或多个视图数据库,其唯一目的是支持查询。使用事件来维护从多个服务腐之数据的只读视图,借此实现对来自多个服务的数据的查询(即读写分离)
1、简介
它将持久化数据模型和使用数据的模块分为两部分:命令端和查询端。命令端模块和数据模型实现创建、更新和删除操作(缩写为CUD,例如:HTTP POST、PUT和DELETE)。查询端模块和数据模型实现查询(例如HTTP GET)。查询端通过订阅命令端发布的事件,使其数据模型与命令端数据模型保持同步。
2、利弊
优势:
1、在微服务架构中高效地实现查询
使用API组合模式实现查询有时会导致大规模数据集的昂贵、低效的内存中连接。对于那些查询,使用易于查询的CQRS视图更有效,该视图预加载(并预处理)来自两个或更多服务的数据。
2、高效地实现多种不同的查询类型
尝试使用单个持久化数据模型支持所有查询通常具有挑战性,并且在某些情况下是不可能的。一些NoSQL数据库具有非常有限的查询功能。即使数据库具有支持特定类型查询的扩展,使用专用数据库通常也更有效。CQRS模式通过定义一个或多个视图来避免单个数据存储的限制,每个视图都有效地实现特定查询。
3、在基于事件溯源技术的应用程序中实现查询
事件存储库仅支持基于主键的查询。CQRS模式订阅由基于事件溯源的聚合发布的事件流,可以保持最新的聚合的一个或多个视图,由此解决此限制。这也是基于事件溯源的应用程序总是使用CQRS的原因。
4、更进一步地实现问题隔离
领域模型及其相应的持久化数据模型不必同时处理命令和查询。CQRS模式为服务的命令端和查询端定义了单独的代码模块和数据库模式。通过隔离问题,命令端和查询端可能更简单,更易于维护。
弊端:
1、更加复杂的架构
开发人员必须编写更新和查询视图的查询端服务。管理和运维额外的数据存储库提高了运维的复杂性。此外,应用程序可能使用不同类型的数据库,这进一步增加了开发人员和运维人员面临的复杂性。
2、处理数据复制导致的延迟
在命令端发布事件和在查询端处理该事件以及更新视图之间存在延迟。更新聚合然后立即查询视图的客户端应用程序可能会看到聚合的先前版本。它必须避免用向用户暴露潜在的不一致性的方式编写CQRS的查询端。
三、CQRS架构
1、设计
CQRS视图模块包括由一个或多个查询操作组成的API。它通过订阅由一个或多个服务发布的事件来更新它的数据库视图,从而实现这些查询操作。视图模块包含视图数据库和三个子模块。
2、存储
可以使用数据结构更加灵活的NoSQL进行存储
3、数据访问模块
数据访问模块需要具备以下特点:
1、支持并发处理
2、具备幂等处理业务逻辑
四、总结
- 实现从多个服务检索数据的查询具有挑战性,因为每个服务的数据都是私有的。
- 有两种方法可以实现这些类型的查询:API组合模式和命令查询职责隔离(CQRS)模式。
- 从多个服务获取数据的API组合模式是实现查询的最简单方法,应尽可能使用。
- API组合模式的局限性是某些复杂查询需要大型数据集的低效内存连接。
- 使用视图数据库实现查询的CQRS模式功能更强大,但实现起来更复杂。
- CQRS视图模块必须处理并发更新以及检测和丢弃重复事件。
- CQRS有助于改善问题隔离,服务不必为自己拥有的数据实现查询功能。
- 客户必须处理CQRS 视图的最终一致性。