什么是从一连串演员那里确认MQ消息的正确方法?

时间:2015-12-30 11:41:06

标签: rabbitmq akka message-queue

我们希望使用Akka来实现从消息队列(RabbitMQ)获取消息然后由一系列actor处理的场景。队列是持久的,不能丢失消息。因此,我们需要将确认(RabbitMQ中的BasicAck)发送回队列,以便最终确定出队消息。因此,处理链中最后一个参与者需要做出确认。这似乎是相当普遍的需求,我想知道是否有一个已知的模式。 Vaughn Vernon在他的书中写到了使用返回地址,因此沿链发送的所有消息都将具有(MQ通道actor的)返回地址和指定队列消息标记的相关标识符。这是正确的方法吗?

另一种方法是在接收后立即发出消息,然后使用持久性演员提供有保证的传递,但我被建议反对这种方法,因为AMPQ的使用消除了演员持久性对于这种特定场景的需要。

1 个答案:

答案 0 :(得分:1)

我对Akka并不熟悉,但我认为我得到了它的功能(非常类似于Erlang中的“进程” - 我认为 - 这就是RMQ的基础)。

一般来说,你对Vaughn Vernon的书的第一个建议是要走的路。

在我的具体情况中,我采用了“中间件”方法来处理您的建议。我的特定中间件实现通过处理消息的一系列命令转发消息本身。每个命令调用action.next()方法继续转发到下一个命令。

在通过中间件发送消息之前,我创建了一个默认的last-command-in-the-chain。此默认命令只调用actions.ack() - 在后台确认消息。

我这样做是为了让命令永远不需要知道如何实际实现完成和继续下一件事的机制。它们具有特定于自身的API,是链中的命令。

这允许我更改确认消息的实现,或者我如何处理来自RMQ等的消息,而不直接更改命令。

Ack'ing the message会立即引入危险,因为你的演员可能会崩溃,Akka本身可能会崩溃,并且可能(并且会)会发生许多其他问题,你将更有可能丢失这条消息。

但请记住 - 没有100%完美的设置。在某些时候,您将丢失一条消息或两次处理相同的消息。您的系统需要在某些时候以某种方式处理这些场景。你所做的一切都是朝着正确的道路前进,以减少这种可能性,但是没有任何东西可以在100%的时间内防止崩溃和消息丢失。