RabbitMQ后续消息原子性

时间:2016-06-07 20:42:21

标签: transactions rabbitmq atomicity

我有一个RabbitMQ消息结构,消息A应该生成大量消息,让我们称之为BC。工作进程收到消息A,然后处理该消息并生成消息BC

假设的工作流程如下:

  1. 使用A
  2. 接收消息ack=False
  3. 开始交易
  4. 运行一些代码
  5. 生成消息B
  6. 生成消息C
  7. 发送ack邮件A
  8. 完成交易
  9. 在任何情况下,工作进程在处理消息A期间死亡,或者当尚未完成事务时 - 我希望RabbitMQ将消息A视为未传递并重新排队它

    如果相关,RabbitMQ将以高可用性配置运行。

    为什么问题是尝试清除RabbitMQ文档here,说明:

      

    此外,即使在仅涉及单个队列的事务的情况下,RabbitMQ也不提供原子性保证,例如,在tx.commit期间发生的故障可能导致在代理重启后,事务的发布子集出现在队列中。

    • 我有没有办法在RabbitMQ或市场上任何其他排队软件的环境中实现我想要的行为?
    • 有什么办法可以让RabbitMQ为多个队列服务吗?

3 个答案:

答案 0 :(得分:0)

您需要相当多的基础架构(代码)才能使其正常工作。这很棘手。

您可能需要考虑服务总线。我在这里有一个免费的.net开源软件:http://shuttle.github.io/shuttle-esb/

如果您不在.net空间或对使用服务总线不感兴趣,您可以按照一些代码查看Shuttle.Esb如何处理这些事情:https://github.com/Shuttle/Shuttle.Esb

您可能还想查看此处IdempotenceServicehttps://github.com/Shuttle/Shuttle.Esb.SqlServer/blob/master/Shuttle.ESB.SqlServer/Idempotence/IdempotenceService.cs

当使用idempotence服务器(在处理程序中)时,所有已发送的消息都存储在事务存储中(在本例中类似于sql server),并且仅在消息处理成功完成后发送。

对于在消息处理程序之外发送,可以使用事务发件箱(同样,基于sql server表的队列也可以工作)。

关键是你需要对你的设计进行一些认真思考,这将会很棘手。

答案 1 :(得分:0)

我在定位最流行的产品时犯了一个错误,就像在我看来一样。 ActiveMQ完全支持高可用性和事务,所以我刚刚切换到那里,我的问题就消失了。

答案 2 :(得分:0)

我们有一些系统在生产中完全像这样工作,其基本格式为:

  1. 获取消息A
  2. 做好工作
  3. 确认消息A
  4. 如果步骤#2失败,则消息A被重新排队"并且可以再次拿起。

    当消息发送到队列并成功接收时,该消息将标记为ready。当它被发送给消费者时,它被标记为unacked,直到被所述消费者确认它被从队列中移除。

    在您的示例中,在您确认步骤#6中的消息之前,它仍然处于unacked状态,这意味着如果工作进程在步骤#6之前死亡,则消息将会滑回到 RabbitMQ 中的ready状态,准备发送给另一个工作人员。

    此功能确实依赖于您未明确禁用确认的事实。如果您是,我非常确定邮件会在发送给消费者后立即从队列中删除。