5

Getting stocked while doing with RabbitMQ using Spring-AMQP.

Just need to get a way to configure AutomaticRecoveryEnabled and NetworkRecoveryInterval using Spring-AMQP. There is a direct option to set these flages if you you developing using native RabbitMQ library. But i didn't find a workaround to do the same using spring

Using RabbitMQ Native library(don't need any help)

factory.setAutomaticRecoveryEnabled(true);
factory.setNetworkRecoveryInterval(10000);

Using Spring-AMPQ(need help)

Like above i didn't find any such method while trying with Spring-AMPQ. This is what i am doing now.

@Bean(name="listener")
public SimpleMessageListenerContainer listenerContainer() 
{
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(connectionFactory());
    container.setQueueNames(env.getProperty("mb.queue"));
    container.setMessageListener(new MessageListenerAdapter(messageListener));
    return container;
}

Any help in this regards is highly appreciable. Thanks in advance.

lambodar
  • 3,495
  • 5
  • 34
  • 58

3 Answers3

9

Just to clarify; Spring AMQP is NOT compatible with automaticRecoveryEnabled.

It has its own recovery mechanisms and has no awareness of the underlying recovery being performed by the client. This leaves dangling connection(s) and Channel(s).

I am working on a temporary work-around that will make it compatible (but will effectively disable the client recovery of any connections/channels used by Spring AMQP, while leaving the client recovery in place for other users of the same connection factory.

A longer term fix will require a major rewrite of the listener container to utilize the client recovery code instead.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Thanks for the update Gray Russell.You mean Spring internally will take care of fault tolerance and auto recovery stuff. – lambodar Aug 08 '14 at 06:41
  • Yes, as I said in my comment to Artem's reply, we've had recovery from day 1; automatic for consumers (listener container) and using a `RetryTemplate` in the `RabbitTemplate` for publishers. – Gary Russell Aug 08 '14 at 12:27
  • @GaryRussell what is the best practice right now to configure automatic recovery of a lost connection with a broker node (in a cluster of 3 nodes) and what is the best practice to retry publishing messages? – Adrian Ivan Mar 02 '16 at 15:59
  • The asynchronous consumer (`SimpleMessageListenerContainer` will automatically keep attempting to reconnect, based on its `recoveryInterval`. For the publisher side, add a [`RetryTemplate` to the `RabbitTemplate` as discussed in the reference manual](http://docs.spring.io/spring-amqp//reference/html/_reference.html#template-retry). – Gary Russell Mar 02 '16 at 16:21
  • hI @Gary, can you please give us an update about this issue ? – Lho Ben Sep 14 '20 at 17:55
  • 1
    There is nothing to update; we now reliably co-exist if auto recovery is incorrectly set. by immediately closing the recovered connection. Spring AMQP's inbuilt recovery (which has been there since day 1) is more deterministic than the auto recovery in the amqp-client. It was too much like Whack-A-Mole to keep squashing the corner cases that kept showing up. – Gary Russell Sep 14 '20 at 17:59
1

Well, CachingConnectionFactory has another costructor to apply a com.rabbitmq.client.ConnectionFactory.

So, it just enough to cofigure the last one as a an additional @Bean with appropriate options and inject it to the CachingConnectionFactory.

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • 3
    However, this option is not needed with Spring AMQP - it has had connection recovery (on the consumer side) from day 1. You could use it on the producer side, or simply add a retry template to the `RabbitTemplate` - you might get some undesirable side-effects when using this option with the `SimpleMessageListenerContainer` because the container knows nothing about the recovered consumers. – Gary Russell Aug 07 '14 at 12:59
  • Thanks Artem.I find find our another method(setRecoveryInterval(time in mills)) of SimpleMessageListenerContainer doing the same stuff. By the way default is 5 sec even though you will not use this method, that's really nice. – lambodar Aug 08 '14 at 06:46
  • 2
    Sprint does not recommend this, they even added a warning to this constructor: "Automatic Recovery is Enabled in the provided connection factory; while Spring AMQP is compatible with this feature, it prefers to use its own recovery mechanisms; when this option is true, you may receive 'AutoRecoverConnectionNotCurrentlyOpenException's until the connection is recovered." – Eran H. Jun 21 '17 at 11:53
0

As of version 4.0.0 of the Java client, automatic recovery is enabled by default.

It can be done like this,

ConnectionFactory factory = new ConnectionFactory();
factory.setAutomaticRecoveryEnabled(true);
// connection that will recover automatically
Connection conn = factory.newConnection();
Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197