我一直在寻找用于以下问题的正确消息传递模式:
我有一个队列,其中包含域中每个用户ID的消息,每个消息都是userChanged事件。业务要求是必须以FIFO顺序处理特定用户标识的所有消息,并且如果在处理特定用户标识的消息期间发生错误,则在将该错误标记为已成功处理之前不应再进行处理。必须处理所有消息,并且需要在集群ESB环境中部署此解决方案。
我想将这些事件分解为每个用户ID的FIFO队列,以便我可以并行处理来自不同用户ID的消息,并按顺序处理用户的每条消息。
到目前为止,我已经提出了两个可能的解决方案,涉及Mule和Rabbit,但两者都涉及自定义组件或我不知道的现有组件。
让Mule流读取第一个RabbitMQ队列上的所有消息,其中AMQP入站端点从头部抓取用户ID。然后,它使用AMQP出站端点,如果它不存在,则动态创建一个持久队列,其名称类似于:userChangedEvent-#[flowVars.userid]
,并将消息发布到该队列。自定义组件需要执行以下操作:
一个。创建一个共享对象映射,该映射将标识所有动态amqp侦听器流(如果它不存在)
湾检查映射以查看是否存在userid的侦听器流的实例。如果没有,请添加将侦听userChangedEvent-#[flowVars.userid]
队列的动态amqp侦听器流的实例,并使用userid作为键将其添加到地图中。
C。开始流程。
d。需要将动态流配置为在单线程配置中进行处理,在业务逻辑成功完成后手动确认消息,并在出现错误时停止流程。
让一个amqp入站端点读取队列中的所有消息,然后“整理”路由器将具有相同用户ID的消息路由到该用户ID的可重用业务逻辑流的同一实例,如果创建实例,则创建实例给定用户标识的一个不存在。这种情况的突出问题是: 一个。这样的路由器是存在还是需要开发? 湾业务逻辑流需要在单个线程中执行,因此需要为流的每个实例以持久的方式维护积压的消息。 C。其中一个实例的执行错误应该阻止该实例处理更多消息,直到它被解决。
我想到了一些解决方法,例如将用户ID“分拆”到各种预定义队列(userChangedEvent-0to1000, userChangedEvent-1000to2000, etc)
中,这样我们就可以预定义我们需要的所有流和相关的amqp监听器,并消除对动态流的需求,但这让我感到震惊作为一个不优雅的解决方案。
我觉得必须有一个消息传递模式来解决这个问题,但是我撕掉了我的EIP副本无济于事!任何建议将不胜感激。
更新:这在概念上就是我所追求的,一个带有通道的解复用器(我称之为桶),但我认为动态通道创建(每个用户标识1个)会更好:http://www.coralblocks.com/index.php/2014/06/demultiplexing-with-coralqueue-for-parallel-processing/