我有一种情况,我有一个有两个队列,Q1和Q2的activemq代理。我有两个使用activemessaging的基于ruby的消费者。我们称他们为C1和C2。两个消费者都订阅了每个队列。我在订阅每个队列时设置activemq.prefetchSize = 1。我也设置了ack = client。
考虑以下事件序列:
1)触发长时间运行作业的消息将发布到队列Q1。叫这个M1。
2)M1被分派给消费者C1,开始长时间的操作。
3)触发短作业的两条消息被发布到队列Q2。称这些为M2和M3。
4)M2被派遣到C2,快速完成短期工作。
5)即使C1仍在运行M1,M3也会被分派到C1。它能够调度到C1,因为prefetchSize = 1是在队列订阅上设置的,而不是在连接上。因此,已经调度Q1消息的事实不会阻止调度一条Q2消息。
由于activemessaging消费者是单线程的,因此最终结果是M3坐在C1上等待很长时间,直到C1完成处理M1。因此,M3不会被处理很长时间,尽管消费者C2处于闲置状态(因为它很快就完成了消息M2)。
基本上,无论何时运行长Q1作业,然后创建一大堆短Q2作业,恰好其中一个短Q2作业会停留在等待长Q1作业完成的消费者身上。
有没有办法在连接级别而不是在订阅级别设置prefetchSize?我真的不希望在处理M1时向C1发送任何消息。另一种选择是,我可以创建一个专门处理Q1的消费者,然后让其他消费者致力于处理Q2。但是,我宁愿不这样做,因为Q1消息很少 - Q1的专用消费者会在一天中大部分时间都处于空闲状态。
答案 0 :(得分:2)
activemq.prefetchSize仅在SUBSCRIBE消息上可用,而不是CONNECT,根据其扩展的stomp标头(http://activemq.apache.org/stomp.html)的ActiveMQ文档。以下是相关信息:
动词:SUBSCRIBE
header:activemq.prefetchSize
type:int
description:指定最大值 将要发送的待处理消息数 被派遣到客户端。一旦这个 达到最大值不再有消息 被派遣到客户端 承认一条消息。设置为1表示 非常公平地分发消息 跨消费者在哪里加工 消息可能很慢。
我对此的阅读和体验是,由于M1尚未被确认(b / c您已启用客户端确认),因此该M1应该是订阅上设置的prefetchSize = 1所允许的1条消息。听到它不起作用我很惊讶,但也许我需要进行更详细的测试。您的设置应该符合您想要的行为。
我听说过其他人关于activemq dispatch的散乱,所以这可能是你正在使用的版本的错误。
我要提出的一个建议是,要么嗅探网络流量,看看M1是否因某种原因得到了确认,要么将一些put语句抛入ruby stomp gem以观察通信(这就是我通常结束的事情)在调试stomp问题时做的事情。)
如果我有机会尝试这一点,我会用自己的结果更新我的评论。
一个建议:很可能会发送多个长处理消息,如果长处理消息的数量超过了您的进程数,那么您将处于快速处理消息等待的此修复程序中。
我倾向于至少有一个专门的流程可以快速完成工作,或者换句话说,专门设置一组只能完成更长工作的流程。让所有轮询器消费者进程同时听取长短的结果可能会产生次优结果,无论发送的是什么。进程组是配置使用者收听目标子集的方法:http://code.google.com/p/activemessaging/wiki/Configuration
processor_group名称, * list_of_processors
A processor group is a way to run the poller to only execute a subset of
处理器通过传递名称 poller命令行中的组 参数。
You specify the name of the processor as its underscored lowercase
版本。所以,如果你有一个 FooBarProcessor和BarFooProcessor in 一个处理器组,它看起来像 这样:
ActiveMessaging::Gateway.define do |s| ... s.processor_group :my_group, :foo_bar_processor, :bar_foo_processor end The processor group is passed into the poller like the following: ./script/poller start -- process-group=my_group
答案 1 :(得分:0)
我不确定ActiveMessaging是否支持此功能,但您可以在长处理消息到达时取消订阅其他消费者,然后在处理后重新订阅它们。
它应该会给你带来理想的效果。