微服务中如何使用API组合模式进行查询?| 本月第三次无套路送书!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u012702547/article/details/99543965

本文选自 《微服务架构设计模式》 一书。

在微服务架构中编写查询非常具有挑战性。查询通常需要检索分散在多个服务所拥有的数据库中的数据。但是,你不能使用传统的分布式查询处理机制,因为即使技术上可行,它也会打破服务之间的隔离和封装。下面将介绍一种在微服务架构中实现查询操作的最简单方法——API组合模式。

什么是 API 组合模式

这个模式通过调用拥有数据的服务并组合结果来实现查询操作。下图显示了该模式的结构。它有两种类型的参与者:

  • API组合器:它通过查询数据提供方的服务来实现查询操作。

  • 数据提供方服务:拥有查询返回的部分数据的服务。

上图显示了三个提供方服务。API 组合器通过从提供方服务检索数据并组合结果来实现查询。API 组合器可能是需要数据呈现网页的客户端,例如 Web 应用程序。或者,它可能是一个服务,例如 API Gateway 及后端前置模式 ,这个模式将查询操作公开为 API 接口。

640?wx_fmt=jpeg

是否可以使用此模式实现特定查询操作取决于几个因素,包括数据的分区方式、拥有数据的服务公开的 API 的功能,以及服务使用数据库的功能,等等。例如,即使提供方服务拥有用于检索所需数据的 API,聚合器也可能需要执行大量数据集的低效内存连接。稍后,你将看到使用此模式无法实现查询操作的例子。但幸运的是,有许多场景可以应用这种模式。为了看到它的实际效果,我们来举个例子。

  • 使用 API 组合模式实现 findOrder() 查询操作

findOrder() 查询操作相当于一个简单的基于主键的 equi-join 查询。可以假设每个提供方服务都有一个 API接口,用于通过 orderId 检索所需的数据。因此,采用 API 组合模式来实现 findOrder() 查询操作似乎是合情合理的。API 组合器调用四个服务并将结果组合在一起。下图显示了Find Order Composer的设计。

640?wx_fmt=jpeg

显而易见,API 组合模式非常简单。让我们看一下在应用此模式时必须解决的几个设计问题。

API 组合模式的设计缺陷

使用此模式时,你必须解决两个设计问题:

  • 确定架构中的哪个组件是查询操作的 API 组合器。

  • 如何编写有效的聚合逻辑。

让我们看看每个问题。

由谁来担任 API 组合器的角色

这是你必须做出的一个决定,选择由谁来扮演查询操作的 API 组合器这个角色。你有三个选择。第一个选择,如下图所示,是由服务的客户端扮演 API 组合器的角色。

640?wx_fmt=jpeg

实现 Order Status 视图并在同一局域网上运行的前端客户端(如 Web 应用程序)可以使用此模式有效地检索订单详细信息。对于防火墙之外的客户以及通过较慢网络访问的服务,此选择可能不实用。

第二个选择如下图所示,由实现应用程序外部 API 的 API Gateway 来扮演 API 组合器的角色,用来完成查询操作和查询结果的组合。

640?wx_fmt=jpeg

如果查询操作是应用程序外部 API 的一部分,则此选择有意义。API Gateway 不是将请求路由到另一个服务,而是实现 API 组合逻辑。这种方法使得在防火墙外运行的客户端(例如移动设备)能够通过单个 API 调用有效地从众多服务中检索数据。

第三个选择如下图所示,是将 API 组合器实现为独立的服务。

640?wx_fmt=jpeg

此选择可以用于由多个服务在内部使用的查询操作。此操作还可用于外部可访问的查询操作,由于它们的聚合逻辑过于复杂,因此无法在 API Gateway 中完成查询,必须使用单独的服务。

API 组合器应该使用响应式编程模型

在开发分布式系统时,我们一直努力降低服务之间的延迟。API 组合器应尽可能地并行调用提供方服务,最大限度地缩短查询操作的响应时间。例如,Find Order Aggregator 应该同时调用这四个服务,因为调用之间没有依赖关系。但有时,API 组合器需要一个提供方服务的结果才能调用另一个服务。在这种情况下,它需要按顺序调用一部分(但希望不是全部)提供方服务。

高效执行顺序和并行服务调用混合的逻辑可能很复杂。为了使 API 组合器达到较高的可维护性、性能和可扩展性,它应该使用基于 Java CompletableFuture、RxJava 可观测或其他类似的响应式设计。我将在后面讲 API Gateway 模式的时候再深入讨论这个主题。

API 组合模式的好处和弊端

此模式是在微服务架构中实现查询操作的简单直观方式。但它也有一些缺点:

  • 增加了额外的开销。

  • 带来可用性降低的风险。

  • 缺乏事务数据一致性。

我们来逐一分析。

  • 增加了额外的开销

这种模式的一个缺点是它需要调用多个服务和查询多个数据库,这带来了额外的开销。在单体应用程序中,客户端可以使用单个请求检索数据,这通常会执行单个数据库查询。相比之下,使用 API 组合模式会涉及多个请求和多个数据库查询。因此,它需要更多计算和网络资源,运行应用程序的成本也相应增加。

  • 带来可用性降低的风险

这种模式的另一个缺点是导致可用性降低。如第 3 章所述,操作的可用性随着所涉及的服务数量而下降。因为查询操作的实现涉及至少三个服务:API 组合器和至少两个提供方服务,其可用性将显著小于单个服务的可用性。例如,如果单个服务的可用性为 99.5%,则调用四个提供方服务的 findOrder() 接口的可用性为 99.5%(4+1)=97.5% !

你可以使用几种策略来提高可用性。一种策略是 API 组合器在提供方服务不可用时,返回先前缓存的数据。API 组合器有时会缓存提供方服务返回的数据,以提高性能。它还可以使用此缓存来提高可用性。如果提供方服务不可用,则 API 组合器可以从缓存中返回数据,尽管这些缓存数据可能是过时的。

另一种提高可用性的策略是让 API 组合器返回不完整的数据。例如,假设KitchenService 暂时不可用。findOrder() 查询操作的 API 组合器可以从响应中省略该服务的数据,因为用户界面仍然可以显示其他有用的信息。你将在后面一章中看到有关 API 设计、缓存和可靠性的更多详细信息。

  • 缺乏事务数据一致性

API 组合模式的另一个缺点是缺乏数据一致性。单体应用程序通常使用一个数据库事务执行查询操作。ACID 事务受制于隔离级别的约束,可以确保应用程序具有一致的数据视图,即使它执行多个数据库查询。相反,API 组合模式则是针对多个数据库执行查询。这种方式 存在一种风险,即查询操作将返回不一致的数据。

例如,从 Order Service 检索的 Order 可能处于 CANCELED 状态,而从 Kitchen Service 检索的相应 Ticket 可能尚未取消。API 组合器必须解决这种差异,因为这会增加代码复杂性。更糟糕的是,API组合器可能无法总是检测到不一致的数据,并将其返回给客户端。尽管存在这些缺点,API 组合模式还是非常有用的。你可以使用它来实现许多查询操作。但是有一些查询操作无法使用此模式有效实现。

以上内容摘自《微服务架构设计模式》一书。

《微服务架构设计模式》 作者:[美] 克里斯·理查森(Chris Richardson) 译者:喻勇

作者 Chris Richardson 是世界十大软件架构师之一、微服务架构先驱,这是一本微服务实用落地指南。本书涵盖 44 个架构设计模式,系统解决服务拆分、事务管理、查询和跨服务通信等难题。

易宝支付CTO陈斌、PolarisTech 联合创始人蔡书、才云科技CEO张鑫等多位专家鼎力推荐。

松哥也在做微服务,老实说,微服务技术上并没有太多难点,真正的难点在于如何进行微服务的架构设计,如何进行服务拆分,这是难点,从这个角度来说,这本书值得一看。


接下来就是送书啦,本月第三次无套路送书,4本《微服务架构设计模式》 由“机械工业出版社华章公司”赞助,在此表示感谢。

送书规则:在下方留言区,用一句话证明你是程序员

松哥会挑选 4 位幸运读者,《微服务架构设计模式》包邮到家(平时分享转发、点赞较多的小伙伴获奖概率更大哦~

着急的小伙伴,可以点击阅读原文购买。

640?wx_fmt=gif

天天吹微服务,单体应用有啥不好?

手把手带你入门 Spring Security!

MyBatis 中 @Param 注解的四种使用场景,最后一种经常被人忽略!

给数据库减负的八个思路

Spring Boot 邮件发送的 5 种姿势!

为了帮助前后端分离的新手,我做了一次大胆的尝试!

公司倒闭 1 年了,而我当年的项目上了 GitHub 热榜

Spring Boot 打包成的可执行 jar ,为什么不能被其他项目依赖?

Java 中的 jar ,天天见,可是你知道它的运行机制吗?


640?wx_fmt=png

640?wx_fmt=png你点的每个在看,我都认真当成了喜欢
展开阅读全文

没有更多推荐了,返回首页