微服务 Saga 模式消费者等待响应

10
我想澄清一下组织架构的最佳方式是什么。
我有rest api和微服务架构。我应用了Database per Service模式。
所以让我们假设用户想创建一个订单(电子商务系统)。但是用户可能有信用额度。因此,流程如下:
1. OrderService创建待定订单。然后推送一个关于它的事件。 2. UserService处理该事件并发布超过信用限额的事件或信用已保留的事件。 3. OrderService接收事件并将订单状态更改为已批准或已取消。
看起来都很好。但问题是在这个简单的流程中用户会做什么? 我的意思是:用户发出POST请求/orders然后...
1. Web-service等待直到订单被批准或取消(包括超时)? 2. Web-service返回200 ok,然后用户需要使用一些间隔检查订单状态? 3. 使用web sockets吗? 4. 其他东西?
不幸的是,以上任何选项都有其优点和缺点。
挑战在于我描述的是最简单的情况。实际上,可能涉及数十个服务(甚至第三方服务)。当然,我期望高负载。因此队列可能会填满。请提出解决方案以供讨论。非常感谢您的回答,也希望提供生产就绪系统文档的链接。

1
嗨,David,这个问题已经有一段时间了,你有没有想法? - cYee
4个回答

1
赞一个好问题。如果我们看Saga模式,它提供了在分布式系统中执行类似ACID的事务,但需要做出一些权衡。其中之一是确保回滚,如果任何服务或实体未能按照预期执行。如果有超过5个服务完成Saga,则这可能会变得更加复杂。但是,如果您可以协调,它将是一个高度可扩展的选项。
在这里,我将提出以下建议:
  • 用户进行订单的POST请求
  • OrderService首先与UserService检查信用额度(它可以是REST API调用,因为对于UserService来说可能只是简单的DB调用)
  • 然后,OrderService可以根据从UserService返回的响应进行操作

此方法的优点

  • 用户可以看到即时响应
  • 编写较少的代码,因此易于测试和维护

此方法的缺点

  • 如果有太多的外部(第三方)REST API调用,则此解决方案将无效
  • 它可能引入单点故障
主要的是,所有选项都会有取舍。决定哪个最适合你就在你自己。

0

根据我的经验

遵循我的规则 - 先验证再执行

在UI界面向订单服务发送请求前,需要对订单进行验证。您可以调用用户服务API来获取用户是否可以下单的信息。

步骤1. 在UI上调用用户服务API,验证用户的信用额度。

步骤2. 如果验证成功或失败

步骤3. 根据步骤2的结果采取行动。如果成功,则调用订单服务;如果不成功,则执行其他操作(调用其他服务等)。

优点

  1. 良好的用户体验 - 当尝试下单时,用户会收到验证消息“您无法下单,因为您的额度较低”或类似消息。而不是最后才得到一条消息“您的额度较低/或其他”。

  2. 代码复杂性更低

  3. 更微服务化的架构 -

由于你遵循微服务的原则,如果在orderservice中调用userservice,意味着orderservice依赖于它,或者可以说是紧密耦合 - 在这里你失去了微服务架构的好处。

如果userservice停机会发生什么。客户无法下订单,或者如果您更改userservice响应中的任何内容,则还必须更改orderservice。

如果未来需要更多验证(以调用其他服务)才能下订单,您该怎么办。

  1. 重定向灵活性 - 假设从userservice验证失败,则必须调用其他服务(其他独立的微服务),如果在orderservice中使用其他服务,则服务数量随着项目的增长而增加
  2. 减少对OrderService的请求 - 只有在来自其他服务或其他事情的验证通过时,才会向orderservice发送请求。

因此从我的角度来看

  1. 尽可能使微服务独立。

  2. 先验证再执行。

  3. 良好的用户体验。

  4. 易于处理负载(如果您认为需要)。

有了这些,现在您对 saga 的依赖性更少了。

这只是我的意见-根据您的领域选择最好的方案。


如有任何疑问,请在评论中提出。 - Ashwani Tiwari
我完全同意在客户端进行验证以获得更好的用户体验。谢谢。但是orderservices根本不依赖于userservice。它只是发送一个事件并订阅等待信用保留或超过信用限额的事件。 - David Markwell

0

因信用额度问题取消订单和因物流设施中的叉车碾压包裹而取消订单的区别很小。

因此,一个相对简单的解决方案是在下单时回复订单已接受和状态200,将其放入队列中并异步运行Saga。您应该为用户提供API(和UI)来检查订单状态,并主动发送状态更新,例如账单通过(这是您的第一个Saga)以及订单生命周期中的其他Saga。关于如何发送通知,这取决于使用场景(例如,您可以对系统进行回调-系统集成,但也许您想向最终用户发送电子邮件/短信等)


0
问题是用户在这个简单的流程中会做什么?我的意思是:用户发出POST请求/orders,然后...。
当您的saga正在运行时,您可以向用户回复已创建的orderId,并显示状态为“pending”。该请求应以200结束。
用户如何获取状态?
推送通知、websocket、电子邮件、短信。由您来通知用户事件的状态,成功、失败、等待批准。
1. Web-service awaits until the order gets approved or canceled?
2. Web-service returns 200 ok and the user check the order state with some interval?
3. use web sockets?
4. something else?
  1. 不建议使用。Saga 应该是异步的。等待回复是同步的(请求/响应式)。
  2. 这样做可以起作用,但如果您的 Saga 是长时间运行的,则可能会出现问题,例如:任何需要人员验证/批准的情况。
  3. 在订单创建处于挂起状态后回复 200,这样做是可行的,但有一件事情需要确保您的 WebSocket 处于活动状态,否则您仍然需要通过电子邮件、短信通知他们。

不幸的是,以上任何选项都有其优点和缺点。

你必须选择你的毒药。

挑战在于我描述了最简单的情况。实际上,可能涉及数十个服务(甚至第三方)。当然,我期望高负载。因此队列可能会被填满。

使用编排的 saga(类似于)Netflix conductor, Uber Cadence, Temporal(类似于 Cadence)。这将使您能够像下面展示的那样做一些事情。至少更容易。

Google Shopping API 的流程图以及他们如何处理它。 enter image description here

更多链接:https://developers.google.com/shopping-content/guides/about-orders


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接