我们正在尝试在ActiveMQ 5.9.1之上构建一个作业队列系统。我们在activemq中使用AMQP 1.0支持,目前使用qpid jms库作为客户端代码。
出于作业队列系统的目的,我们可以将预取设置为1至关重要 - 我们希望我们的工作人员一次只能获得一个任务,竞争消费者模式。 qpid库使用连接工厂定义来支持这一点:
connectionfactory.activemq-amqp-manager = amqp://{user}:{password}@{hostname}:{port}?clientid=job-manager&remote-host=default&max-prefetch=1
然而,ActiveMQ似乎完全忽略了这一点,消费者在activemq管理控制台中显示为预取100.
进一步挖掘,我找到了源代码:org.apache.activemq.transport.amqp.AmqpProtocolConverter
包括以下行:
consumerInfo.setPrefetchSize(100);
这是否意味着AMQP 1.0协议的ActiveMQ支持会为所有客户端硬取一个100的预取值?显然这是非常错误的。我们有什么选择?我们可以切换到纯JMS客户端,但会失去语言互操作性。或者我们可以切换到RabbitMQ,这意味着引入另一个产品来支持(ActiveMQ已在其他地方使用)。
答案 0 :(得分:0)
您是否实际进行过任何测试,以确定预取1的消费者是否按预期工作?
ActiveMQ的内部结构并非基于AMQP,因此即使AMQP消费者已连接,事情也不会像您希望的那样完全出现。 AMQP客户端连接的ActiveMQ内部使用者默认为100,但是向客户端分派消息仍然受到远程端设置的当前流窗口的限制。如果QPid客户端在设置预取值时将链接信用限制为1,则代理只会发送一条消息。
这里唯一需要注意的是,每个订阅最初都可以在代理方面进行预取,但最终会在消费者之间进行预取,因为随着更多消费者的加入,代理将进行循环调度。
ActiveMQ中的AMQP支持仍在不断成熟,欢迎您潜入并尝试改进它。