djechlin
djechlin

Reputation: 60748

Automatically reconnect RabbitMQ channels

I found this gem:

In the event of a connection failure, the client will need to establish a new connection to the broker. Any channels opened on the previous connection will have been automatically closed and these will need re-opening too.

So that's not good. I'm about to go write a big layer of handling automatic reconnects and recreating the channels then encapsulate this happening from all of my code. Problem is, this should be done already. Is this possible in the Java RMQ libraries?

Upvotes: 11

Views: 23263

Answers (3)

falconizer
falconizer

Reputation: 418

Perhaps this is a new feature of the RabbitMQ client, but I found this in their docs:

To enable automatic connection recovery, use factory.setAutomaticRecoveryEnabled(true):

https://www.rabbitmq.com/api-guide.html

Looks like it should solve the problem.

Upvotes: 9

djechlin
djechlin

Reputation: 60748

As of RabbitMQ 3.3.0 (April 2014) this is possible with Java clients.

This release . . . allows Java-based clients to reconnect automatically after network failure.

I don't know if this is a server-only change, a change to the client libraries only that makes this possible, etc. Still researching.

Upvotes: 2

theMayer
theMayer

Reputation: 16157

Yes, I agree this is a major disadvantage of the current RabbitMQ client implementations. I have been using RMQ for about 2 years now (the .NET library), and not much has changed about it in that time. It needs to be completely re-written from the ground up, and I just haven't had time to do it yet.

But I do have some pointers. First, I would create a wrapper class for your connection/channel object (you need the channel to do AMQP operations, the only thing the connection is used for is to create channels). Then, your wrapper class can keep track of whether the channel or connection is open, and act accordingly.

My code ends up looking like this:

while (_iNeedToBeSendingAndReceiving) {
try {

//This blocks indefinitely while waiting for a connection.
using (var channel = ConnectionWrapper.CreateChannel(string connectionString) {

  //Do stuff, blah, blah
  //When the connection or channel closes, an exception is thrown and
  //I move to the catch block.
  }    
  catch(ConnectionInterruptException ex) {
  //Eat, yummy!
  }
}

My eventual plan is to abstract even this stuff away, and create a completely new way of interacting with the RabbitMQ (or any other messaging) library. I'll let you know when I've gotten some work done on this, it could be a couple months.

Upvotes: 1

Related Questions