How to disable RabbitMQ prefetch count with Simple

2019-07-23 16:53发布

问题:

RabbitMQ offers the ability to optionally set a prefetch count.

Using spring-amqp's SimpleMessageListenerContainer, I've noticed the prefetch count is always set. I cannot set the prefetch count to 0, because SimpleMessageListenerContainer sets it to at least txSize which must be greater than zero (even when there are no transactions involved). So is there a way to disable the prefetch count, i.e. make it unlimited?

Here is the relevant code from spring-amqp:

SimpleMessageListenerContainer.createBlockingQueueConsumer() does this:

    int actualPrefetchCount = prefetchCount > txSize ? prefetchCount : txSize;

and BlockingQueueConsumer.start() does this:

    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);
        }

What is the reasoning behind always calling basicQos() in Springs's BlockingQueueConsumer? Isn't there any use case for disabling the prefetch count? (except auto-ack obviously).

The rabbitmq documentation discusses the overhead of setting prefetch count with a channel (global) scope. It is not explicitly mentioned whether setting it with a consumer scope has any overhead compared to not setting it at all. If I'm not mistaken spring always sets it with a consumer scope. Does it indeed have no overhead at all? Still it seems strange not having the option to not set it.

Thanks

回答1:

Since the current implementation hands off to an internal queue, due to the way earlier rabbitmq clients worked, not setting the qos will cause an OOM condition if the consumer can't keep up.

In fact, with earlier versions of Spring AMQP, this would happen with auto ack so the queue is bounded according to the prefetch size to stop the broker from sending messages under this condition.

In 2.0, we are planning a new container implementation that avoids this queue since the rabbit client no longer has the issues that required it. We can consider supporting qos=0 then.