RabbitMQ提供了可选择设置预取计数的功能。
使用spring-amqp的SimpleMessageListenerContainer
,我注意到预取计数始终设置。我无法将预取计数设置为0,因为SimpleMessageListenerContainer
将其设置为至少txSize
,它必须大于零(即使没有涉及事务)。那么有没有办法禁用预取计数,即使其无限制?
以下是spring-amqp的相关代码:
SimpleMessageListenerContainer.createBlockingQueueConsumer()
这样做:
int actualPrefetchCount = prefetchCount > txSize ? prefetchCount : txSize;
和BlockingQueueConsumer.start()
执行此操作:
if (!acknowledgeMode.isAutoAck()) {
// Set basicQos before calling basicConsume (otherwise if we are not acking the broker
// will send blocks of 100 messages)
try {
channel.basicQos(prefetchCount);
}
总是在Springs的BlockingQueueConsumer
中调用basicQos()后面的原因是什么?是否有禁用预取计数的用例? (显然除了auto-ack)。
The rabbitmq documentation讨论了使用通道(全局)范围设置预取计数的开销。没有明确提到是否设置消费者范围与没有设置消费者范围相比有任何开销。如果我没弄错的话,春天总会把它放在一个消费者范围内。它确实没有开销吗?似乎很奇怪没有选择不设置它。
由于
答案 0 :(得分:1)
由于当前实现移交到内部队列,由于早期rabbitmq客户端工作的方式,如果消费者无法跟上,则不设置qos将导致OOM条件。
事实上,对于早期版本的Spring AMQP,这将发生在auto ack中,因此队列根据预取大小限制,以阻止代理在这种情况下发送消息。
在2.0中,我们是planning a new container implementation that avoids this queue,因为兔子客户端不再存在需要它的问题。我们可以考虑支持qos = 0。