zhaoyu@home:~$

微服务设计模式-微服务中的查询

使用API组合模式查询

在微服务的查询中,有在本服务的,也有跨服务的查询,一下以findOrder()作为例子来讲解。

findOrder()查询操作

order信息包括了status,payment status 等基本信息,在微服务中,订单需要的信息存在多个不同的服务中。API组合模式,调用多个服务 获得数据,并将他们组装到一起。它有两种参与者组成:

  1. API composer——查询provider service,并组装数据。
  2. Provider service——包含查询需要数据的service。

如下图所示:

一个API Composer可能是一个客户端,也可能是一个service,如API网关。 在API组合模式中需要明确两点:

  1. 在你的架构中,哪个组件是API composer。
  2. 如何实现高效的数据组合逻辑。
API composer角色

第一种选择,前台客户端如web应用。这种在LAN运行高效,但是在防火墙外通过较慢的网络访问时,不太可行。

第二种选择,API网关,它实现了应用外部的API,可以扮演一个API composer角色。

第三种选择,用一个标准的服务实现API composer。这种在外部查询逻辑非常复杂时使用。

尽管,API组合模式简单,但是还是有一些缺点:

  1. 增加负载,相对于单个应用,增加了请求和查询数据的次数,更多的计算和网络被消耗。
  2. 可用性降低,由于一次查询被分为多次查询,每次查询有可能会失败,那么整体成功的概率会降低。可以在某次查询失败时,使用缓存数据。 或者返回不完整的数据。
  3. 事务数据一致性缺失,由于api组合模式分多次查询,那么有可能导致查询的结果不一致。如,查询订单的状态是Canceled,而在查询Ticket 时,还没有被cancel。

使用CQRS

许多企业应用使用了RDBMS用于数据保存,并使用ES或者solr用于文字检索。一些应用通过同时向两者写入数据,保持数据库的同步。另一些, 则通过从RDBMS复制数据到搜索引擎来同步数据。CQRS是这种架构的一种扩展。它拥有一个或者多个数据库,不只是文本搜索引擎。

使用CQRS的原因

有很多API组合模式很难实现的查询,这个时候就需要CORS了。

findOrderHistory()

查询历史订单,有consumerId,pagination,filter(如订单状态,restaurant名称等)。这时候检索条件可能在不同的服务中,再加上分页和 排序,根本无法实现。

findAvailableRestaurants()

实现从多个服务获取数据的查询是非常困难的,但是有些场景下,从单个服务中获取数据也非常困难。如在某时某地获取可用的餐馆。这个查询 的核心是一定距离的地理搜索。当然MongoDB,Mysql等提供了地理扩展,支持地理数据类型,索引及查询。但是如果信息是存在不支持地理 检索的数据库中,那么就需要维护一份数据的副本,将它存放在支持地理检索的数据库中,类似于使用搜索引擎查询文本。

CQRS概述

CQRS就是将查询和命令分离,CQRS和non-CQRS区分如下:

CQRS不仅可以被用于一个服务,而且还可以定义为一个独立的查询服务,该服务只有查询api,如findOrderHistory()创建一个Order History Service,从其他服务中订阅事件: