微服务架构中的 Saga Orchestration 可扩展性问题
Saga Orchestration Scability Issue in Microservice Architecture
我需要在微服务架构中处理分布式事务。理论上,最好的方法之一是使用 Saga Orchestration 模式。问题是我找不到任何关于如何提供可伸缩性的详细信息。
让我们使用下面的示例。 CreateOrderSaga可以有很多个,如果我有多个OrderService.API就会这样。因为我可以拥有不止一个OrderService.API。那么如果 CreateOrderSaga 是一种状态机,那么它是否意味着它应该自己处理其中的所有步骤,或者其他协调器可以接替它的工作?
然后,如果那个 API 在 运行 传奇进程中崩溃了怎么办,其他传奇协调器是否可以继续 运行 与崩溃 API 相同的状态剩下?处理这种情况的最佳方法是什么?事件存储有何帮助?
我来详细解释一下
Order.APIs 之一中的 Coordinator1 启动 CreateOrderSaga
Coordinator1 中的 CreateOrderSaga 创建一个订单,该订单具有
待定状态
然后 Coordinator1 由于某种原因崩溃了。 (也许没电了)订单保持待定状态,现在没有人感兴趣。应该有人继续处理或者标记为失败(谁有责任)也许还需要一些补偿交易。
那么是否可以让 saga 协调器启动一个进程但其他人也可以继续处理它?
如何扩展 saga 协调器?
解法:
我确实选择了 Masstransit 来管理分布式事务
Saga 模式应该作为异步过程来实现。在这种情况下 asynchronous
表示基于消息。大多数类型的消息队列都有确认功能(rabbitmq)。在这里我将描述无状态服务(即可以在 OrderService
的不同实例中处理 CreateOrder
请求)。
您点击"make an order"按钮,CreateOrder
消息被发送到消息队列,OrderService
从队列接收这条消息。它被缩放是因为您可以创建 OrderService
.
的许多实例
那么我们有两种情况:
1.
Orchestration-based saga:OrderService
接收消息,实例化协调器,协调器消费 CustomerService
。如果 OrderService
在消息处理完成之前失败,CreateMessage
消息将不会在消息队列中被确认。随后,OrderService
的另一个实例将接收消息并尝试处理它。如果 CustomerService
在调用期间失败:您可以使整个 CreateOrder
消息失败并稍后重试,或者重试对 CustomerService
.
的特定调用
2.
Choreography-based saga:OrderService
收到一条消息并尝试处理该消息。如果失败,则情况相同:消息将不会被确认,并将重新发送以供稍后重试。这种方法是关于发出 OrderCreated
、CustomerCreated
等事件(即它是面向事件的)
当然,您应该为您的服务配置监控和警报,以确保系统处于活动状态并能够处理消息。
您还应该考虑是否需要实施一些补偿逻辑或检查。想象一下:您在处理一条消息时向不同的服务发出了两个 HTTP POST 请求,第一个服务调用成功完成但第二个服务调用失败。如果您重试整个 CreateOrder
消息 - 您不应再次调用第一个服务。
进一步阅读:overview of sagas, coordinating sagas, choreography-based sagas:
In order for the communication to be reliable, it’s essential that the
saga participants use a message broker that guarantees at-least-once
delivery and has durable subscriptions. That’s because at-least-once
delivery and durable subscriptions ensure that a saga completes even
if a participant is temporarily unavailable. A message will sit in the
message broker’s channel (e.g. queue or topic) until the participant
is able to successfully process it.
要了解如何正确实施它,请阅读 NServiceBus sagas framework 的实施方式。它是 sagas 的 .NET 框架,但概念与语言无关。
我需要在微服务架构中处理分布式事务。理论上,最好的方法之一是使用 Saga Orchestration 模式。问题是我找不到任何关于如何提供可伸缩性的详细信息。
让我们使用下面的示例。 CreateOrderSaga可以有很多个,如果我有多个OrderService.API就会这样。因为我可以拥有不止一个OrderService.API。那么如果 CreateOrderSaga 是一种状态机,那么它是否意味着它应该自己处理其中的所有步骤,或者其他协调器可以接替它的工作?
然后,如果那个 API 在 运行 传奇进程中崩溃了怎么办,其他传奇协调器是否可以继续 运行 与崩溃 API 相同的状态剩下?处理这种情况的最佳方法是什么?事件存储有何帮助?
我来详细解释一下
Order.APIs 之一中的 Coordinator1 启动 CreateOrderSaga
Coordinator1 中的 CreateOrderSaga 创建一个订单,该订单具有 待定状态
然后 Coordinator1 由于某种原因崩溃了。 (也许没电了)订单保持待定状态,现在没有人感兴趣。应该有人继续处理或者标记为失败(谁有责任)也许还需要一些补偿交易。
那么是否可以让 saga 协调器启动一个进程但其他人也可以继续处理它?
如何扩展 saga 协调器?
解法:
我确实选择了 Masstransit 来管理分布式事务
Saga 模式应该作为异步过程来实现。在这种情况下 asynchronous
表示基于消息。大多数类型的消息队列都有确认功能(rabbitmq)。在这里我将描述无状态服务(即可以在 OrderService
的不同实例中处理 CreateOrder
请求)。
您点击"make an order"按钮,CreateOrder
消息被发送到消息队列,OrderService
从队列接收这条消息。它被缩放是因为您可以创建 OrderService
.
那么我们有两种情况:
1.
Orchestration-based saga:OrderService
接收消息,实例化协调器,协调器消费 CustomerService
。如果 OrderService
在消息处理完成之前失败,CreateMessage
消息将不会在消息队列中被确认。随后,OrderService
的另一个实例将接收消息并尝试处理它。如果 CustomerService
在调用期间失败:您可以使整个 CreateOrder
消息失败并稍后重试,或者重试对 CustomerService
.
2.
Choreography-based saga:OrderService
收到一条消息并尝试处理该消息。如果失败,则情况相同:消息将不会被确认,并将重新发送以供稍后重试。这种方法是关于发出 OrderCreated
、CustomerCreated
等事件(即它是面向事件的)
当然,您应该为您的服务配置监控和警报,以确保系统处于活动状态并能够处理消息。
您还应该考虑是否需要实施一些补偿逻辑或检查。想象一下:您在处理一条消息时向不同的服务发出了两个 HTTP POST 请求,第一个服务调用成功完成但第二个服务调用失败。如果您重试整个 CreateOrder
消息 - 您不应再次调用第一个服务。
进一步阅读:overview of sagas, coordinating sagas, choreography-based sagas:
In order for the communication to be reliable, it’s essential that the saga participants use a message broker that guarantees at-least-once delivery and has durable subscriptions. That’s because at-least-once delivery and durable subscriptions ensure that a saga completes even if a participant is temporarily unavailable. A message will sit in the message broker’s channel (e.g. queue or topic) until the participant is able to successfully process it.
要了解如何正确实施它,请阅读 NServiceBus sagas framework 的实施方式。它是 sagas 的 .NET 框架,但概念与语言无关。