我有消息表示发送到队列的两个用户之间的操作。 用户存储为消息的属性。 要求不允许在同时处理关于一个或另一个用户的不同动作时处理[从队列中获取]动作。
由于我使用Grails(意思是Spring)和ActiveMQ,我想过以这种方式实现它:
使用事务创建MessageListenerContainer,当侦听器读取它将获得事务状态的消息时,检查userA或userB当前是否处理了一个操作,并根据结果 - 处理action或rollback jms事务。 我考虑过创建一个简单的地图来存储当前处理过的用户的详细信息:
{
userId : [listenerId, timestamp]
}
我想存储侦听器ID和时间戳,以便有一种方法可以简化错误处理[还没到达那里]。
因此,在处理操作之前,userId将放在那里,在操作完成后,密钥将被删除。
不幸的是,我在原型设计时遇到了一个重大问题。当我回滚消息时,监听器将等待并再次读取相同的消息。 这意味着如果我为userA获得5个动作并且只有5个侦听器,则在处理第一个动作时整个过程将被卡住。那不是我想要的。 我希望监听器读取消息,检查是否可以处理操作,如果没有读取下一条消息。 甚至可以实施吗?
在我的原型中有一个监听器,当我发送5条消息然后回滚时,这就是我得到的[这是来自读者:读取消息时的时间戳+消息号码]:
1288892171570 0
1288892171578 0
1288892176582 0
1288892181586 0
1288892186589 0
1288892191594 0
1288892196596 0
1288892201601 1
1288892206604 1
1288892211607 1
1288892216612 1
1288892221614 1
1288892226618 1
1288892231621 1
1288892236625 2
1288892241629 2
1288892246632 2
1288892251636 2
1288892256641 2
1288892261645 2
1288892266647 2
1288892271652 3
1288892276656 3
1288892281659 3
1288892286663 3
1288892291667 3
1288892296671 3
1288892301674 3
1288892306679 4
1288892311682 4
1288892316686 4
1288892321689 4
1288892326693 4
1288892331696 4
1288892336700 4
重新递送政策是AMQ 5.4.1的默认值。 我想看到的是: 0,1,2,3,4,0,1,2,3,4,0,1,2,3,4 ...
我认为它应该以某种方式工作,当一个事务被回滚并且消息被标记为重新传递时,它将被延迟但是监听器将继续工作。此外,当重新传递消息时,它将返回到队列中的位置 - 队列是[应该?]按消息时间戳排序。
示例[假设所有5条消息同时发送]: 读取消息0,执行检查,可以处理 - >处理 读取消息1,执行检查,无法处理,事务回滚,延迟X个时间量 读取消息2,执行检查,无法处理,事务回滚,延迟X量的时间 读取消息3,执行检查,无法处理,事务回滚,延迟X个时间量 消息1重新传递为X时间已过,执行检查,无法处理,事务回滚,延迟X时间 读取消息4 .....
我不确定我尝试做的是否可行,或者我是否应该考虑采取其他方式?我认为这样简单,易于扩展。 也许这只是AMQ配置的问题,但我确实看起来没有在重新传递设置中找到任何有用的东西。
谢谢, 克里斯蒂安
答案 0 :(得分:0)
这似乎是Active MQ的“功能”:https://issues.apache.org/activemq/browse/AMQ-1853 撰写本文时的问题是等待审核,但是包含可以使用Camel实现的解决方案的链接。 而且我认为这是我将要去的方式[至少现在]。 我将创建两个队列: actionsQueue busyQueue
侦听器将从actionsQueue执行操作,并将测试是否可以处理操作。 如果没有,它会将消息发送到busyQueue。 我将在busyQueue上监听并自动将消息路由到具有配置延迟的actionsQueue。
如果我想使用原始想法实现它,似乎这是前进的方向。
我仍然想知道是否有更好的方法来做到这一点。