在微服务中编写查询非常具有挑战性,查询通常需要检索分数在多个服务所拥有的数据库中的数据,但不能使用传统的分布式查询处理机制,即使技术可行,也会打破服务之间的隔离和封装。
在微服务架构中实现查询有两种不同的模式:
findOrder()查询操作:从多个服务获取数据的查询方法
什么是API组合模式
API组合模式:通过查询每个服务的API并组合结果,实现从多个服务检索数据的查询
其有两种类型的参与者:
是否可以使用此模式实现特定查询操作取决于几个因素,包括数据的分区方式、拥有数据的服务公开的API的功能,以及服务使用数据库的功能。
使用API组合模式实现findOrder()查询操作
由谁来担任API组合器的角色
可选:客户端(web等)、api gateway(简单逻辑)、独立的服务(复杂逻辑)
应该使用响应式编程模型
API组合模式的优缺点
优点:实现查询操作简单直观
缺点:
命令查询职责隔离(CQRS)模式:使用事件来维护从多个服务复制数据的只读视图,借此实现对来自多个服务的数据的查询。
CORS是这中架构的概况,通常维护一个或者多个试图数据库,实现一个或者多个应用程序的查询。
为什么要使用CQRS
什么是CQRS
CORS将持久化数据模型和使用数据的模块分为两部分:命令端和查询端。命令端模块和数据模型实现创建、更新和删除操作(CUD),查询端模块和数据模型实现查询(R)。查询端通过订阅命令端发布的事件,时期数据模型与命令端数据模型保持同步。
CQRS和查询专用服务
查询端服务订阅多个服务发布的事件,这种视图(和数据)不属于任何特定服务,因此将其实现为独立的服务是合理的。
查询服务也是实现复制单个服务所拥有的数据的好方案,可以把查询的实现和服务的功能分隔开。
CQRS的优缺点
优点
缺点
CQRS视图模块包括由一个或者多个查询操作组成的API,通过订阅由一个或者多个服务发布的事件来更新它的数据库视图,从而实现这些查询操作。
视图模块包含视图数据库和三个子模块:
选择视图存储库
SQL数据库
NoSQL
支持更新操作:
如果你需要 | 使用 | 例如 |
基于主键的JSON对象查找 | 文档型数据库,例如MongoDB或者DynamoDB,或者Redis键值存储数据库 | 通过维护包含每个客户的MongoDB文档来实现订单历史记录 |
基于查询的JSON对象查找 | 文档型数据库,例如MongoDB或者DynamoDB | 使用MongoDB或DynamoDB实现客户视图 |
文本查询 | 文本搜索引擎,例如Elasticsearch | 通过维护每个订单的Elasticsearch文旦来实现订单的文本搜索 |
图查询 | 图数据库,例如Neo4j | 通过维护客户、订单和其他数据图表来实现欺诈检测 |
传统的SQL报表/BI | 关系型数据库 | 标准业务报告和分析 |
设计数据库访问模块
事件处理程序和查询API模块不直接访问数据库存储区。相反,它们使用数据访问模块,该模块由数据访问对象(DAO)及其辅助类组成。
当视图订阅由多个聚合类型发布的事件时,多个事件处理程序可能同时更新同一记录,DAO必须能够正确处理这种情况。
为了确保可靠,事件处理程序必须记录事件ID并以原子化的方式更新数据存储区,如何执行此操作取决于数据库的类型。
事件处理程序不需要记录每个事件的ID,每个记录仅需要存储从给定聚合实例接收的max(eventId)。
执行更新命令后执行查询命令可能看不到更新前的数据 ,视图是最终一致的。
为了检测不一致,命令端操作可以将包含已发布事件和ID标记返回给客户端,然后客户端将事件有关的ID传递给查询操作,如果该事件尚未更新视图,则返回查询错误。视图模块可以使用重复事件检测机制来实现这样的功能。
添加和更新CQRS视图
添加和更新CQRS视图在概念上很简单,即:创建新视图:开发查询端模块、设置数据存储区并部署服务。查询端模块的事件处理程序处理所有事件,最终视图将是最新的。更新现有视图:更改事件处理程序并从头开始重构视图。
但在实际中会产生一些问题,消息代理无法无限期存储信息。如:RabbitMQ会在消费者处理完消息后删除该消息,Apache Kafka可在配置的保留期内保留消息,但也不会无限期存储事件。
解决办法:使用归档事件构建CQRS视图,使用可扩展的大数据技术(如Apache Spark)实现。
处理所有事件所需的时间和资源随着时间推移而不断增长。
解决办法:增量式构建CQRS视图,使用两步增量算法。第一步基于先前的快照和自创建快照以来发生的事件,定期计算每个聚合实例的快照。第二步使用快照和任何后续事件创建视图。
留言与评论(共有 0 条评论) “” |