3
votes

After my app loses connection to the RabbitMQ Server, I see in the log

ERROR ... o.s.a.r.c.CachingConnectionFactory : Channel shutdown: connection error

And then when my app reconnects to RabbitMQ Server, I see in the log

INFO ...  Created new connection: SimpleConnection@7d9717bc [delegate=amqp://******]

However when the app reconnects to RabbitMQ Server, The channels are not reopened, in the RabbitMQ Admin Console, I can see in the 'Channels' tab that there aren't any.

In the RabbitMQ Server log after the reconnection:

=INFO REPORT==== 13-Jul-2017::10:33:39 ===
accepting AMQP connection (*.*.*.*:* -> *.*.*.*:5672)

=INFO REPORT==== 13-Jul-2017::10:33:39 ===
Connection (*.*.*.*:* -> *.*.*.*:5672) has 
a client-provided name: rabbitConnectionFactory#1

=INFO REPORT==== 13-Jul-2017::10:33:39 ===
connection (*.*.*.*:* -> *.*.*.*:5672 - 
rabbitConnectionFactory#1): user '***' authenticated and granted access to vhost '***'

I'm using Spring Boot 1.5.3 and spring-boot-starter-amqp

It looks like Spring AMQP 1.7 disables the rabbitmq client's 'enableAutomaticRecovery', and uses it's own recovery mechanism

The 4.0.x client enables automatic recovery by default; while compatible with this feature, Spring AMQP has its own recovery mechanisms and the client recovery feature generally isn’t needed. It is recommended to disable amqp-client automatic recovery, to avoid getting AutoRecoverConnectionNotCurrentlyOpenException s when the broker is available, but the connection has not yet recovered. Starting with version 1.7.1, Spring AMQP disables it unless you explicitly create your own RabbitMQ connection factory and provide it to the CachingConnectionFactory. RabbitMQ ConnectionFactory instances created by the RabbitConnectionFactoryBean will also have the option disabled by default.

I'm not sure if this has anything to do with the issue.

Note that if I shutdown my app and restart it, it behaves as expected.

1

1 Answers

3
votes

Spring AMQP turns off the automaticRecovery by default:

private static com.rabbitmq.client.ConnectionFactory newRabbitConnectionFactory() {
    com.rabbitmq.client.ConnectionFactory connectionFactory = new com.rabbitmq.client.ConnectionFactory();
    connectionFactory.setAutomaticRecoveryEnabled(false);
    return connectionFactory; 
}

You can turn it on via RabbitConnectionFactoryBean:

/**
 * Set to true to enable amqp-client automatic recovery. Note: Spring AMQP
 * implements its own connection recovery and this is generally not needed.
 * @param automaticRecoveryEnabled true to enable.
 * @since 1.7.1
 */
public void setAutomaticRecoveryEnabled(boolean automaticRecoveryEnabled) {
    this.connectionFactory.setAutomaticRecoveryEnabled(automaticRecoveryEnabled);
}

The Spring AMQP out-of-the-box automatic recovery is good for the listener container, but I guess you deal with RabbitTemplate. So, consider to switch it on: http://docs.spring.io/spring-amqp/reference/html/_reference.html#auto-recovery