【问题标题】:Grouping data together in Microservices在微服务中将数据分组在一起
【发布时间】:2021-06-08 18:45:00
【问题描述】:
假设我在微服务架构中有两个服务:-
OrderService
CustomerService
每个服务都有自己的数据库,我的前端现在向/api/order/25 发出请求以及我想返回CustomerName 的命令,但CustomerName 在不同的数据库中。那么获取CustomerName 和Order 数据的最佳和最基于微服务的方法是什么?
【问题讨论】:
标签:
api
rest
architecture
microservices
【解决方案1】:
您有多种选择。例如:
-
复制 OrderService 数据库中的一些客户数据。例如,您可以将实体的一小部分作为单独的表保存在 Order 服务数据库中,例如:CustomerId 和 CustomerName。这非常适用于您在 /api/order/id 端点上有大量流量但客户数量非常少的用例。这意味着在您的 OrderService 数据库中复制一些客户数据不会很昂贵。如果您有一个用于在 CustomerService 中的客户数据更改时发布事件消息的微服务之间通信的消息队列,则此选项非常有效。通过这种方式,您可以更新 OrderService 数据库中的客户数据,并及时了解数据的真实来源。如果您没有用于通信的消息队列,则此选项不会很好,因为您需要定期检查 CustomerService 中的更改。这会给 CustomerService 带来额外的负载,并且 OrderService db 中的 Customer 数据会在一段时间内不一致。这个选项的好处是,即使您对“/api/order/id”有很多调用,CustomerService 也不会受到此负载的影响,因为数据已经在 OrderService 数据库中。
-
当您需要该数据时,从 OrderService 调用 CustomerService。 在此选项中,每次您需要 CustomerName 和其他 CustomerService 数据时,您都需要通过一些 api 调用 CustomerService。例如,当有人调用您的“/api/order/id”端点时,您将从 OrderService 调用 CustomerService api。如果您对此 api 的调用次数不多并且通常 CustomerService 上的负载不大,则此选项非常好。这样,这种额外的调用不会有很大的问题。如果您对“/api/order/id”有很多调用,并且负载也委托给了 CustomerService,这将成为一个问题。
-
创建第三个微服务,它将聚合来自 CustomerService 和 OrderService 的数据。在此选项中,您将拥有另一个具有自己的数据库的只读微服务,该数据库将包含数据来自两个微服务在自己的数据库中。如果您有一个必须处理大量负载的系统,此选项可能很有用,特别是对于此特定端点有很大的潜在负载:“/api/order/id”或其他使用聚合的端点来自多个微服务的多个实体。如果您想将其分离并独立扩展,您可以创建另一个微服务,如客户订单微服务,并从 CustomerService 和 OrderService 复制数据。与选项 1 类似。您只需复制所需实体的特定字段/属性。使用此选项,您甚至可以拥有某种去规范化的数据结构,您可以将实体存储在一个表/集合中(如果您需要它:))。如果您有一些全文搜索要求等,您甚至可以使用更适合您查询的选择数据存储技术,例如 Elastic Search。这项特殊服务可以根据您的需要来满足您的需求。一些例子也在CQRS等方向的Query/Read部分。您可以在这里做很多选择。这是特定用例的一个选项,因此您需要仔细审查您的业务需求并根据您的需要进行调整。
结论
通常在大多数情况下,您可以使用选项 1 或选项 2。但很高兴知道您也可以决定使用选项 3 并拥有一个特殊的只读/仅查询服务,该服务可以满足您的特殊需求。请记住,服务之间的通信方式也会影响您的选择。你可以阅读更多关于微服务到微服务的通信here。
【解决方案2】:
在这种情况下,我建议创建一个聚合器服务或后端换前端。
该服务将从这两个服务中获取数据并将其聚合到您的前端(或您的客户端)。
通过这种方式,您的订单服务不需要依赖客户服务来获取名称,或者您的客户不需要再次调用来获取数据并进行聚合。
与 BFF,
- 您可以添加针对每个客户的需求量身定制的 API,从而消除由于将其全部保存在一个位置而造成的大量臃肿。
- 前端需求将与后端关注点分开。这样更容易维护。
- 客户端应用程序对 API 结构的了解更少,这将使其对这些 API 的更改更具弹性。
但是,所有这些微服务模式都需要权衡取舍,BFF 也不例外。
所以请始终牢记,
- BFF 是客户端和服务之间的转换/聚合层。从服务 API 返回数据时,其目的是将其聚合并转换为客户端应用程序指定的数据类型。
- 避免过度依赖BFF,不要在这一层添加应用逻辑。正如我在上一步中所说,它只是一个翻译器。
- 实施弹性设计和超时,因为此聚合器正在调用其他服务并获取数据。如果一个或多个服务调用花费的时间太长,它应该超时并返回部分数据集。考虑您的应用程序将如何处理这种情况
- 监控您的聚合器及其子服务调用。使用相关 ID 实现分布式跟踪以跟踪每个调用。