rabbitmq/rabbitmq-java-client

Sending messages with confirmation to a full queue of limited size can lead to high channel churn

groundhog2k opened this issue · 0 comments

Scenario:
On RabbitMQ side an exchange and a queue was configured. The queue has a binding to the exchange.
The queue has a limited size and an overflow behavior "reject-publish".

A spring based java application client is sending messages to the exchange using the rabbitmq-java-client library and waits for confirmation of every sent message - or until a timeout happens.
When the queue is full the client will receive "nack" messages as exceptions.

The problem is, that under the hood (inside the rabbitmq-java-client implementation), every "Queue full" response from RabbitMQ will lead to a closed channel.
This can be seen in the code at: https://github.com/rabbitmq/rabbitmq-java-client/blob/main/src/main/java/com/rabbitmq/client/impl/ChannelN.java#L241
It happens exactly in Line 248.

When the message rate of published messages is very high, it causes the effect that a lot of new channels will be opened and closed - and Pooled channels can not be reused anymore, because they were already closed by mentioned line of code.
That all ends in high channel churn which is described in https://www.rabbitmq.com/channels.html#high-channel-churn and also pooling of channels will not work anymore.
High channel churn can then lead to more resource usage (memory, cpu) on RabbitMQ side and so on...

Is there a better way to differentiante between the "queue full" case and other potential errors and handle the different cases better inside https://github.com/rabbitmq/rabbitmq-java-client/blob/main/src/main/java/com/rabbitmq/client/impl/ChannelN.java#L241.

In my opinion it is not necessary to close a channel in case of "queue full" - it can still be reused.

This affects all versions of the rabbitmq-java-client.