12

I have an anonymous and exclusive queue defined like this:

@Bean 
    public SimpleMessageListenerContainer responseMessageListenerContainer(){
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(simpleRoutingConnectionFactory());
        container.setQueues(responseAnonymousQueue());
        container.setMessageListener(rabbitTemplate());
        container.setAcknowledgeMode(AcknowledgeMode.AUTO);
        container.setMessageConverter(jsonMessageConverter());
        return container;
    }

@Bean
    public Queue responseAnonymousQueue() { 
        return new MyAnonymousQueue();
    }

Sometimes I get this error en rabbitmq log:

=ERROR REPORT==== 12-Apr-2016::15:13:42 === Channel error on connection <0.6899.0> (XX.XXX.57.174:51716 -> 192.168.100.145:5671, vhost: '/', user: 'XXXX_USER'), channel 1: {amqp_error,resource_locked, "cannot obtain exclusive access to locked queue ' XXXX_USER-broad-1457bb43-6487-4252-b21a-a5a92d19e0dc' in vhost '/'", 'queue.declare'}

So the client can’t declare the queue and it can’t receive the messages from the AMQP server.

It happens after this message:

=WARNING REPORT==== 12-Apr-2016::15:11:51 === closing AMQP connection <0.6810.0> (XX.XXX.57.174:17959 -> 192.168.100.145:5671): connection_closed_abruptly

=INFO REPORT==== 12-Apr-2016::15:13:41 === accepting AMQP connection <0.6899.0> (XX.XXX.57.174:51716 -> 192.168.100.145:5671)

I can’t reproduce it (I have tried closing the connection from rabbitmq and removing the network cable, but the application reconnect well again), so I don’t know exactly why is this happening. It is supposed that private and exclusive queues are deleted with the closing of the connection, so why is this happening? How can I catch this exception and recover from it?

Thanks

jandres
  • 439
  • 1
  • 7
  • 21

2 Answers2

10

You are correct, exclusive queues are deleted when the connection that declared it; this implies that that connection is still open and it wasn't declared by the connection you see in the log.

When your system is in that condition, go to the admin UI where you can explore the queue and which connection owns it.

e.g. Exclusive owner 127.0.0.1:60113

If that shows the closed connection (XX.XXX.57.174:17959 in the example above) you should reach out to the rabbitmq guys on the rabbitmq-users google group, this does not appear to be a spring-amqp issue;

EDIT

FYI, if passive queue declaration fails for any reason, by default the consumer will try 3 times at 5 second intervals, then give up and stop the container.

There are two properties on the container that can be used to adjust this - declarationRetries and failedDeclarationRetryInterval (default 3 and 5000 respectively). If you are using <rabbit:listener-container /> configuration, there are equivalent attributes on the namespace.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Thank you, I will ask to the rabbitmq guys. And how could I detect this error to display an error message? – jandres Apr 14 '16 at 13:40
  • I am not sure what you mean; the container already logs such errors. Starting with version 1.5, you can add an `ApplicationListener` bean to the context to receive an event when the consumer won't start for any reason. – Gary Russell Apr 14 '16 at 13:53
  • I have the 1.4.4.RELEASE version in that proyect, is there another option to receive the event and show it to the user? – jandres Apr 14 '16 at 14:40
  • No, just the log message. – Gary Russell Apr 14 '16 at 14:42
  • I have found one way to reproduce the problem: changing the network. If you are connected by wifi, and switch to another wifi, then the connection is restored, but the old connection takes time to disappear, so private queues still exist when the second connection is created, and therefore the application cant subscribe to them with the new connection. – jandres Apr 14 '16 at 14:42
  • Interesting; I wonder if you can try to delete the queue during initialization. You could add a custom `ConnectionListener` make sure it is registered with the connection factory before the `RabbitAdmin` and try a delete. This will run before the container tries to consume. But I am not sure if a "foreign" connection is allowed to delete an exclusive queue. – Gary Russell Apr 14 '16 at 14:46
  • I'll try, but I think if the queue is locked it will give me the same error. The same happens if you try to delete an exclusive queue from the management plugin. – jandres Apr 14 '16 at 14:50
  • That doesn't sound promising then. By the way, with 1.4 and later, the container will eventually recover and re-declare the queue when it detects it is missing. – Gary Russell Apr 14 '16 at 15:54
  • I can see this in the log console: "Queue declaration failed; retries left=1", "Consumer received fatal exception on startup" and at the end: "Stopping container from aborted consumer", so the container does not recover. – jandres Apr 15 '16 at 06:53
  • Oh, right sorry, yes, by default we try 3 times at 5 second intervals, then give up and stop the container. There are two properties on the container that can be used to adjust this - `declarationRetries` and `failedDeclarationRetryInterval` (default 3 and 5000 respectively). If you are using `` configuration, there are equivalent attributes on the namespace. – Gary Russell Apr 15 '16 at 12:35
1

Check the queue name should not bound with an exchange otherwise you will get this error. Or I think queue name already exists.

Atul Jain
  • 1,035
  • 2
  • 16
  • 24