-
Notifications
You must be signed in to change notification settings - Fork 10.2k
RabbitMQ queue bindings are lost after a reconnection #1701
Description
Hello there,
I was checking the auto-reconnect mechanism of RabbitMQ. Then I found that after a reconnection to RabbitMQ, the exchange and all queues are restored but the bindings between them are lost.

After carefully tracing the code and the RabbitMQ document, I think I might have the idea. The document states that
The following steps are performed for every channel known to being open at the time of connection failure:
- Re-declare exchanges (except for predefined ones)
- Re-declare queues
- Recover all bindings
- Recover all consumers
It means that if we want the bindings to be recovered after reconnection, channels must be opened at the time of connection failure. But in the DoInternalSubscription method, we use "using" to declare a channel, so the channel is being disposed when leaving the "using" section.
private void DoInternalSubscription(string eventName)
{
var containsKey = _subsManager.HasSubscriptionsForEvent(eventName);
if (!containsKey)
{
if (!_persistentConnection.IsConnected)
{
_persistentConnection.TryConnect();
}
using (var channel = _persistentConnection.CreateModel())
{
channel.QueueBind(queue: _queueName,
exchange: BROKER_NAME,
routingKey: eventName);
}
}
}
Maybe we can use the _consumerChannel which is created at the constructor instead, rather than declare a new channel whenever needs to bind a queue to an exchange? What do you think?
The document also states that
Much like connections, channels are meant to be long lived. That is, there is no need to open a channel per operation and doing so would be very inefficient, since opening a channel is a network roundtrip.
So I think the fix might also improve the performance as well?
I have tested the approach and it works without issue. I am happy to create a PR if needed :)
How to reproduce
- Launch the project using docker-compose ( I was using visual studio)
- Stop the RabbitMQ container
- Wait services start trying to reconnect
- Start the RabbitMQ container
- Go to RabbitMQ admin UI to check bindings