microservices - DDD 中的编排 Sagas - 集成事件链?

标签 microservices domain-driven-design saga

我目前正在研究 Saga 模式。大多数示例似乎都集中在 Orchestration Sagas 上,我们有一个中央 saga 执行协调器服务来发送和接收消息/事件。不幸的是,似乎缺少有关如何实现 Choreography Sagas 的信息。

在领域驱动设计中,我们有多个限界上下文,理想情况下,每个限界上下文都是一个独立的微服务。如果微服务 A 想要与另一个微服务 B 通信,我们使用 Integration Events。使用一些异步通信发布和订阅集成事件 - RabbitMQ、Azure 服务总线。

假设我们想要启动一些 Saga,例如,我们必须在订单服务和客户服务上运行事务——服务之间究竟如何通信?它只是常规的集成事件还是完全不同的事情?

我看到它的方式和下面给出的图片(source),Saga 将以这种方式执行:

  1. 创建了一个新订单。状态设置为“待处理”并发出 OrderSubmittedDomainEvent 域事件。
  2. 域事件处理程序接收 OrderSubmittedDomainEvent 域事件,然后创建并调度 ReserveCreditIntegrationEvent 集成事件。
  3. 客户服务接收 ReserveCreditIntegrationEvent 集成事件。
  4. 它试图保留客户信用。
  5. 如果成功保留信用,则发出 CustomerCreditReservedDomainEvent 域事件。
  6. 域事件处理程序收到 CustomerCreditReservedDomainEvent 域事件,它创建并调度 CreditReservedIntegrationEvent 集成事件。
  7. 订单服务接收 CreditReservedIntegrationEvent 集成事件并将订单状态设置为“已确认”。
  8. saga 完成。

这是正确的方法吗?

Saga

最佳答案

我认为对于分布式事务使用编排而不是编排是有意义的,如果你选择它是为了正确的话原因。例如,如果您需要省去实现中央编排通常需要付出的更多努力,因为您不需要知道事务处于什么状态,直到它完成。或者因为您知道交易工作流的顺序是稳定的并且不太可能改变,这也对编排有利。但如果顺序频繁更改,这将是编排的一个缺点,因为在这种情况下您需要调整所有微服务...

因此您需要了解这两种方法的优缺点。

如果您出于正确的原因选择编排,我会说我在您的考虑中遗漏了补偿逻辑。如果预留信用但订单服务中订单失败怎么办?在这种情况下也需要考虑补偿事件......

除此之外还有常见的嫌疑人:

  • 例如确保每个服务在处理接收到的事件后可靠地发送下一个事件。为此,您可以查看 Transactional Outbox 模式。
  • 或者确保您在每个服务中实现了事件重复数据删除,以便跨分布式事务可靠地发送事件,您不能百分百确定事件只会发送一次。

如果您甚至对 Saga 模式的替代方案感兴趣,您可以查看 Routing Slip 模式。它非常适合分布式事务工作流,这些工作流将根据当前用例而有所不同,避免每个服务需要知道每个路由。工作流的顺序附加到事务的初始消息和所有后续消息。然后,每个收到带有路由单的消息的服务都会执行其任务,并将包含路由单的下一条消息传递给列表中的下一个站点(服务)。

注意:我不确定您所说的...IntegrationEvent 到底是什么意思。我不会区分 domainintegration 事件,在您的示例中,从业务角度来看,所有事件都是相关的,否则它们将与其他微服务无关。

关于microservices - DDD 中的编排 Sagas - 集成事件链?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63597403/

相关文章:

domain-driven-design - CQRS/事件溯源,如何获得一致的数据来应用业务规则?

android - React Native API 实现导致错误

java - 如何使用事件源(axon 框架)处理传奇中从 REST-API 传递的多个实体?

nservicebus - 如何防止多次启动 NServiceBus 传奇?

java - Netflix Feign - 通过微服务传播状态和异常

c# - 如果实体处于某种状态,如何强制执行约束,例如任何字段(或特定字段)不得更改?

asp.net-core - 启用二进制媒体类型会中断 AWS Lambda 中的选项 POST 调用 (CORS)

java - 服务层和领域模型的问题

security - 如何为微服务创建公钥存储?

caching - 存储另一个服务的数据是否违反微服务的单一职责原则