You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.
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
The text was updated successfully, but these errors were encountered:
Hi @alan0428a, sorry for the delay in responding. Thank you for identifying the issue and sharing the details repro steps 👍
Yes, your right. If the RabbitMQ container/pod gets restarted, the binding between the exchange and queues were lost. We don't need to create the channel everytime, instead we could use a common _consumerChannel like the connection _persistentConnection If you could submit a PR, we will be happy to review and merge the changes.
Also, in the k8s environment, the same repro steps should fetch similar results, if we delete the RabbitMQ pod. You may want to check that too.
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
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.
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
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
The text was updated successfully, but these errors were encountered: