如果一项服务仅是 REST API不是基于消息的,如何执行 SAGA

问题描述

我正在尝试理解 SAGA(又名。流程管理器 - 确切的命名不是这个问题的一部分)。

所有 SAGA 教程都说 SAGA(基于编排)发送消息(命令)并接收(处理)传入消息,例如:

SagaStart
Send: MakeStep1
Receive: Donestep1
Send: MakeStep2
Receive: Donestep2
SagaDone

如果:

  • 参与此 SAGA 的服务以消息驱动的方式实现
  • 服务知道 SAGA 的协调器传入消息队列(因此​​实际上与它耦合,因为它们必须知道将结果消息发送到哪里)

如果有一个只公开 REST API 的服务怎么办?然后它看起来像这样:

SagaStart
result1 = HttpClient.Post(step1url); // 'MakeStep1' done with API call
Send: MakeStep2
Receive: Donestep2;
SagaDone

这种方法看起来不像 SAGA。是吗?

问题是:您可以将 SAGA 与仅 API 的服务一起使用吗?怎么样?

解决方法

saga 是一个有状态的长时间运行的进程,通常包含一个状态机定义。 saga 的传入消息需要确定它们适用于哪个状态,以及将作为输入应用到状态机的负载(以及当前状态)。

因此,没有理由不能仅使用 REST API 来实现传奇 ,但您是否真的想要这样做可能是一个更好的问题。消息代理和总线可以为您做很多事情,并且比自己动手做更好。这些东西要正确实施并不容易,使用正确的工具会消除很多麻烦,让您专注于业务需求而不是基础架构和框架。

一个简单的例子;如果在您的端点接收到的相同 saga 状态的两条消息足够接近,以至于第一个在第二个到达之前尚未完成执行 - 您将如何处理?处理状态时的这种异步问题是一个关键因素。

诸如异步行为、消息关联、状态机定义、状态存储和生命周期、错误处理、有毒消息等问题都是找到一个为您处理这些东西的框架的好理由。考虑查看 Spring Boot、MassTransit 和其他类似产品。