从不同的微服务中收集数据的正确方法是什么?

时间:2018-06-04 01:37:39

标签: node.js architecture microservices

我在理解应该如何进行微服务之间的基本通信时遇到问题,而且我无法在其他问题中找到一个好的解决方案或标准方法来执行此操作。让我们使用这个基本的例子。

enter image description here

我的发票服务会返回发票,每张发票都会包含有关用户和产品的信息(ids)。如果我有一个视图,我需要为特定用户呈现发票,我只是提出一个简单的请求。

let url = "http://my-domain.com/api/v2/invoices"
let params = {userId:1}
request(url,params,(e,r)=>{
  const results = r // An array of 1000 invoices for the user 1
});

现在,对于此特定的视图,我需要再次请求获取每张发票上每种产品的所有详细信息。

results.map((invoice)=>{
   invoice.items.map((itemId)=>{
      const url=`http://my-domain.com/api/v2/products/${itemId}`
      request(url,(e,r)=>{
       const product = r
       //Do something else.....
      });
   });
});

我知道代码示例并不完美,但你可以看到这会产生大量的产品服务请求(至少1000个),而且仅针对1个用户,现在想象一下,如果我有1000个用户制作这种请求。

在不必提出此类请求数量的情况下,为了避免性能问题,从所有产品中获取信息的正确方法是什么?

我找到了一些解决方案,例如:

  1. 创建一个接受ID列表的API端点,以便发出单个请求。
  2. 复制发票服务中产品服务的信息,并找到一种方法使其保持同步。
  3. 在微服务架构中,这些是处理这类问题的正确方法吗?对我来说,它们看起来像是简单的解决方法。

    编辑#1:基于Remus Rusanu的回应。

    根据Remus的建议,我决定隔离我的服务并对它们进行更好的描述。

    enter image description here

    如上图所示,微服务现在已被隔离(特定于计费服务),现在他们是数据的所有者。通过使用此结构,我确保即使有异步作业,或即使其他两个服务都已关闭,Billing-service也能够正常工作。

    如果我需要创建新发票,我可以同步调用另外两个微服务(用户,库存),然后在我的结算服务中更新“缓存”表(用户,库存)上的数据。

    假设这些“缓存”表是只读的也是好的吗?我假设他们是因为只有用户/库存服务应该能够修改这些信息,以保持对信息的隔离和权限。

2 个答案:

答案 0 :(得分:1)

这完全取决于您的弹性要求。当其他微服务关闭或不关闭时,您是否希望您的微服务正常运行?

您提出的第一个解决方案是弹性较低:如果任何用户或产品微服务发生故障,Invoice微服务也会下降。这是你想要的吗?另一方面,这种架构是最简单的。这种架构的一种变体是让客户端发出加入请求;这导致了一个讨厌的对话,但它的优势在于,当其他微服务关闭时,客户端可以用默认信息替换丢失的信息。

第二种解决方案提供了最大的弹性,但它更复杂。在这种情况下,拥有事件驱动的架构有很大帮助。在这种架构中,微服务充当swimming lanes。其中一个微服务的故障不会传播到其他微服务。

答案 1 :(得分:1)

您需要隔离服务,因为它们不共享状态/数据。您的问题中的设计是单个宏服务,分为3个相关的存储孤岛。举个例子,您无法解释“开票”服务的结果,无法将数据与“产品”响应相关联。

隔离的微服务意味着他们拥有自己的数据,并且可以独立运行。从“发票”服务返回的发票已完成。它包含产品名称,客户名称,发票上的每个信息。所有数据都来自自己的存储。一个单独的微服务可能是'库存',它运行所有产品库存,当前库存等。它也有自己的数据,在自己的存储中。 “产品”可以存在于两种存储介质中,并且它们之间曾经存在逻辑链接(创建发票时),但现在链接已被切断。 “库存”微服务可以改变其产品(例如,移除一个,添加新的SKU等),而不影响现有的发票(这不仅是微服务隔离要求,也是基本的会计要求)。我不打算在这里详细介绍现实生活中的产品“身份”。

如果你发现自己问的问题就像你问的那样可能意味着你没有微服务。您应该考虑在微服务边界,同时考虑如果用基于异步排队的请求替换所有通信会发生什么(响应可能在6天之后出现):如果语义中断,边界可能是错误的。如果语义成立,那就是正确的轨道。