简体   繁体   English

Axon 框架:在两个或三个微服务之间具有补偿事件的 Saga 项目

[英]Axon Framework: Saga project with compensation events between two or three microservices

I have a question about Axon Saga.我有一个关于 Axon Saga 的问题。 I have a project where I have three microservices, each microservice has his own database, but the two "Slave" microservice has to share his data to the "Master" microservice, for that I want to use the Axon Saga.我有一个项目,我有三个微服务,每个微服务都有自己的数据库,但是这两个“从”微服务必须将他的数据共享给“主”微服务,为此我想使用 Axon Saga。 I already asked a question about the compensation, when something goes wrong, and I have to deal with the compensation by myself, it is ok, but not ideal.我已经问过关于赔偿的问题,出了问题,我必须自己处理赔偿,可以,但不理想。 Currently I am using the DistributedCommandBus to communicate between the microservices, is it good for that?目前我正在使用 DistributedCommandBus 在微服务之间进行通信,这有好处吗? I am using the Choreography Saga model, so here is what it is look like now:我正在使用 Choreography Saga 模型,所以它现在是这样的:

  1. Master -> Send command -> Slave1 -> Handles event Master -> Send command -> Slave1 -> 处理事件
  2. Slave1 -> Send back command -> Master -> Handles event Slave1 -> Send back command -> Master -> 处理事件
  3. Master -> Send command -> Slave2 -> Handles event Master -> Send command -> Slave2 -> 处理事件
  4. Slave2 -> Send back command -> Master -> Handles event Slave2 -> Send back command -> Master -> 处理事件

If something went wrong then comes the compensating Commands/Events backwards.如果出现问题,则补偿命令/事件会倒退。

My question is has anybody did something like this with Axon, with compensation, what the best practices for that?我的问题是有没有人用 Axon 做过这样的事情,有补偿,最好的做法是什么? How can I retry the Saga process?如何重试 Saga 进程? With the RetryScheduler?使用 RetryScheduler? Add a github repo if you can.如果可以,请添加 github 存储库。

Thanks, Máté谢了哥们

First and foremost, let me answer your main question:首先,让我回答你的主要问题:

My question is has anybody did something like this with Axon?我的问题是有人对 Axon 做过类似的事情吗?

Shortly, yes, as this is one of the main use cases of for Sagas.很快,是的,因为这是 Sagas 的主要用例之一。 As a rule of thumb, I'd like to state a Saga can be used to coordinate a complex business transaction between:根据经验,我想说明一个 Saga 可用于协调以下之间的复杂业务交易

  1. Several distinct Aggregate Instances几个不同的聚合实例
  2. Several Bounded Contexts几个有界上下文

On face value, it seems you've landed in option two of delegating a complex business transaction.从表面上看,您似乎已经进入了委托复杂业务交易的选项二。

It is important to note that when you are using Sagas, you should very consciously deal with any exceptions and/or command dispatching results.需要注意的是,当您使用 Sagas 时,您应该非常有意识地处理任何异常和/或命令调度结果。

Thus, if you dispatch a command from the "Master" to "Slave 1" and the latter fails the operation, this result will come back in to the Saga.因此,如果您从“Master”向“Slave 1”发送命令并且后者操作失败,则该结果将返回到 Saga。 This thus gives you the first option to retry an operation, which I would suggest to do with a compensating action .因此,这为您提供了重试操作的第一个选项,我建议使用补偿操作来实现 Lastly, with a compensating action, I am talking about dispatching a command to trigger it.最后,通过补偿动作,我指的是调度一个命令来触发它。

If you can not rely on the direct response from dispatching the command, retrying/rescheduling a message within the Saga would be a reasonable second option.如果您不能依赖调度命令的直接响应,则在 Saga 中重试/重新调度消息将是合理的第二个选择。

To that end, Axon has the EventScheduler and DeadlineManager .为此,Axon 拥有EventSchedulerDeadlineManager Note that the former of the two publishes an event for everyone to see .请注意,两者中的前者发布了一个事件供大家查看 The latter schedules a DeadlineMessage within the context of that single Saga instance, thus limiting the scope of who can see a retry is occurring.后者在单个 Saga 实例的上下文中安排了DeadlineMessage ,从而限制了谁可以看到重试发生的范围。

Typically, the DeadlineManager would be my preferred mode of operation for thus, unless you require this 'rescheduling action' to be seen by everybody.通常, DeadlineManager将是我首选的操作模式,除非您要求每个人都看到此“重新安排操作”。 FYI, check this page for EventScheduler information and this page for DeadlineManager info.仅供参考,请查看页面的EventScheduler信息和页面的DeadlineManager信息。

Sample Update示例更新

Here's a bit of pseudo-code to get a feel what a compensating action in a Saga Event Handler would look like:这里有一些伪代码来感受一下 Saga 事件处理程序中的补偿动作是什么样的:

class SomeSaga {

    private CommandGateway commandGateway;

    @SagaEventHandler(assocationValue = "some-key")
    public void on(SomeEvent event) {
        // perform some checks, validation and state setting, if necessary
        commandGateway.send(new MyActionCommand(...))
                      .exceptionally(throwable -> {
                                         commandGateway.send(new CompensatingAction(...));
                                     });
    }
}

I don't know your exact use case, but from this and your previous question I get the impression you want to roll back, or in this case undo, the event if one of the event handlers cannot process it.我不知道你的确切用例,但是从这个和你之前的问题我得到的印象是你想要回滚,或者在这种情况下撤消事件,如果其中一个事件处理程序无法处理它。

In general, there are some things you are able to do.一般来说,您可以做一些事情。 You can see if the aggregate that applied the event in the first place has or can have the information to check whether the 'slave' microservice should be able to handle the event before you apply it.您可以查看首先应用事件的聚合是否具有或可以拥有信息来检查“从”微服务是否应该能够在应用之前处理事件。 If this isn't practical, the slave microservice can also apply a 'failure' event directly on the eventbus to inform the rest of the system that a failure state has occurred that needs to be handled:如果这不切实际,从属微服务还可以直接在事件总线上应用“失败”事件,以通知系统的其余部分发生了需要处理的故障状态:

https://docs.axoniq.io/reference-guide/implementing-domain-logic/event-handling/dispatching-events#dispatching-events-from-a-non-aggregate https://docs.axoniq.io/reference-guide/implementing-domain-logic/event-handling/dispatching-events#dispatching-events-from-a-non-aggregate

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM