【发布时间】:2010-11-05 06:31:14
【问题描述】:
我将表示两个用户之间的操作的消息发送到队列。 用户存储为消息的属性。 要求是在同时处理涉及一个或另一个用户的不同操作时,不允许处理[从队列中获取的]操作。
由于我使用的是 Grails(即 Spring)和 ActiveMQ,因此我考虑过以这种方式实现它:
创建一个带有事务的 MessageListenerContainer,当监听器读取消息时,它将获取事务的状态,检查 userA 或 userB 是否正在处理当前的操作,并根据结果 - 处理操作或回滚 jms 事务。 我想创建一个简单的地图来存储有关当前处理的用户的详细信息:
{
userId : [listenerId, timestamp]
}
我想存储侦听器 ID 和时间戳,以便有一种方法可以简化错误处理 [还没有到达那里]。
所以在处理操作之前 userId 会被放在那里,在操作完成之后 key 会被移除。
不幸的是,我在制作原型时遇到了一个大问题。当我回滚消息时,侦听器将等待并再次阅读相同的消息。 这意味着如果我为 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 条消息同时发送]: 读取Msg 0,进行校验,可以处理->处理 读取消息 1,执行检查,无法处理,事务回滚,延迟 X 时间 读取消息 2,执行检查,无法处理,事务回滚,延迟 X 时间 读取消息 3,执行检查,无法处理,事务回滚,延迟 X 时间 消息 1 在经过 X 时间后重新传递,已执行检查,无法处理,事务回滚,延迟 X 时间 消息 4 被读取.....
我不确定我尝试做的事情是否可取,还是应该考虑以其他方式做?我认为这种方式会简单且易于扩展。 也许这只是 AMQ 配置的问题,但我确实在重新传递设置中查看并没有找到任何对这里有帮助的东西。
谢谢, 克里斯蒂安
【问题讨论】: