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

时间:2019-06-05 08:21:18

标签: java cqrs event-sourcing saga axon

所以目前我正在使用事件源和CQRS来实现轴突框架的传奇。

情况如下:

我有3个微服务,分别是m1,m2和m3

用户在GUI中输入3个实体e1,e2,e3的数据,分别由m1,m2,m3处理和保留,因此m1-> e1,m2-> e2,m3-> e3

现在有了传奇的必要性:

没有e2不能存在e1,没有e3不能存在e2。

因此,必须通过各自的服务成功创建所有3个实体,如果一个实体失败,则传奇需要执行补偿交易以确保一致性。 首先,m1创建e1,发出e1CreatedEvent,协调器发送createE2Command作为对此的响应。

现在我的问题:

如何获取/存储用户输入的信息?在一个RequestBody中?那我该怎么处理这些数据?因为需要某种方式对其进行缓存才能与命令一起发送。

例如,m1创建一个createE1Command并将来自e1的信息添加到其中,然后在成功创建后,协调器将启动createE2Command,然后将e2的信息添加至该命令,然后再发送给它。发生这种情况时,需要以某种方式存储e2的信息,直到需要它为止。

示例代码:

@Saga
public class ManagementSaga{

@Autowired
private transient CommandGateway commandGateway

@StartSaga
@SagaEventhandler
public void handle (e1CreatedEvent e1CreatedEvent){


  commandGateway.send (new CreateE2Command (e1CreatedEvent.Id, **HERE NEEDS TO BE THE INFO THAT THE USER CREATED PREVIOUSLY**)}}

我是否仅创建一个对象来保存这三个实体的信息?感觉真不对。

现在我了解到,选择这样一种域模型也许真的很糟糕,如果可能的话,应该避免使用它,但这是出于科学目的:-)

1 个答案:

答案 0 :(得分:2)

在这种情况下,我的第一反应是完全质疑设计。似乎(微)服务是围绕实体设计的。这种设计在某些情况下可能会起作用,但在其他情况下不可避免地会导致分布式整体。您面临的挑战暗示了后者。

从API的角度和系统的设计方式来看,交互似乎也不匹配。虽然不是每个定义都错误,但这也可能表示API不正确(不能正确反映系统的行为)或行为模型不正确。

无论如何要给您一个比“取决于它”更有用的答案,您可以在多个命令甚至查询中获得单个交互结果。并非在所有情况下都需要佐贺。

发出一个有关E1,E2和E3信息的单个请求。然后在您的控制器中,发送命令以创建E3,然后根据该命令的结果创建E2,最后创建E1。无需“缓存”任何信息。请求信息在整个过程中都可用。但是,这种方法不是事务性的。如果服务崩溃,则可能会使进程半执行。

一种替代方法是让命令处理程序注册用户的原始意图。那不是要创建E1,E2或E3,而是要包含所有这三个。流程生成的事件会触发Saga单独执行每个步骤,并使用这些步骤中的事件来触发下一步。此过程具有最终一致性特征。

我希望这有道理。但是,我会认真地重新考虑服务的模型/设计,使它们更多地关注流程(步骤),而不是实体(状态)。我已经看到太多的微服务项目由于以实体为中心的设计而失败...