RabbitMQ: connection recovery mechanism

I am using the client library for mb 3.4.1 java rabbit and cannot get the auto recovery mechanism.

Here's how I create a rabbit factory mk mix:

factory = new ConnectionFactory(); factory.setUsername(userName); factory.setPassword(password); factory.setVirtualHost(virtualHost); factory.setAutomaticRecoveryEnabled(true); factory.setNetworkRecoveryInterval(5); factory.setRequestedHeartbeat(3); 

After posting the message, if I close the mq broker rabbit and return it again, I expect the recovery mechanism to start working and restore the connection to the β€œnormal” state. But I get the following error:

 com.rabbitmq.client.AlreadyClosedException: connection is already closed due to connection error; protocol method: #method<connection.close>(reply-code=320, reply-text=CONNECTION_FORCED - broker forced connection closure with reason 'shutdown', class-id=0, method-id=0) at com.rabbitmq.client.impl.AMQChannel.ensureIsOpen(AMQChannel.java:190) ~[amqp-client-3.4.1.jar:na] at com.rabbitmq.client.impl.AMQChannel.transmit(AMQChannel.java:291) ~[amqp-client-3.4.1.jar:na] at com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:654) ~[amqp-client-3.4.1.jar:na] at com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:631) ~[amqp-client-3.4.1.jar:na] at com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:622) ~[amqp-client-3.4.1.jar:na] 

Am I missing something? The only way around this problem is to register the ShutDownListener and reinitialize the rabbit factory mq connection, connection and channels.

Also to answer

"chrislott"

comment, I see that system recovery is being restored to restore. I create an exchange using a temporary channel:

 Channel channel = connection.createChannel(); channel.exchangeDeclare(exchangeName, exchangeType, durable); channel.close(); 

And I see the following exception when trying to restore the topology:

 Caught an exception when recovering topology Caught an exception while recovering exchange testSuccessfulInitVirtualHost_Exchange: channel is already closed due to clean channel shutdown; protocol method: #method<channel.close>(reply-code=200, reply-text=OK, class-id=0, method-id=0) com.rabbitmq.client.TopologyRecoveryException: Caught an exception while recovering exchange testSuccessfulInitVirtualHost_Exchange: channel is already closed due to clean channel shutdown; protocol method: #method<channel.close>(reply-code=200, reply-text=OK, class-id=0, method-id=0) at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.recoverExchanges(AutorecoveringConnection.java:482) at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.recoverEntities(AutorecoveringConnection.java:467) at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.beginAutomaticRecovery(AutorecoveringConnection.java:411) at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.access$000(AutorecoveringConnection.java:52) at com.rabbitmq.client.impl.recovery.AutorecoveringConnection$1.shutdownCompleted(AutorecoveringConnection.java:351) at com.rabbitmq.client.impl.ShutdownNotifierComponent.notifyListeners(ShutdownNotifierComponent.java:75) at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:574) 

The above exception is not visible unless I close the channel used to create the exchange.

+5
source share
2 answers

My reading of the RabbitMQ ConnectionFactory # setAutomaticRecoveryEnabled (Boolean) method is that it primarily provides recovery after a NETWORK failure.

Here's a nice discussion: https://www.rabbitmq.com/api-guide.html

For example, if your machine loses the route to the broker within a certain period of time, possibly due to a switch or other failure, then automatic recovery may restore the connection, etc. The document says nothing about the survival / reboot of the broker, I do not think your expectation is reasonable.

IMHO for recovering from a restart of the broker, the shutdown-listenener approach seems to be a robust approach.

+2
source

Typically, the rabbit client should handle the recovery on its own β€” you should not manually override it. At least try using lyra .

I had some problems during testing on failure. Connections, as a rule, begin to hang on the broker reboot, therefore the exception of the stop signal was the last in the logs. I installed it by installing:

 factory.setConnectionTimeout(20_000); 

Also, the recovery is not very well reflected in the timelines. If you have those, you may have to do some extra processing (again, try lyra first).

+1
source

All Articles