2

Components Involved: Spring Config-server, Spring AMQP (RabbitMQ), Spring Config-client

Goal: Use push notification to inform config-client to refresh config.

  • RabbitMQ instance: From docker hub, I pulled rabbitmq:3-management image and ran.
  • Config-client AMQP version pom.xml:

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        <version>1.3.1.RELEASE</version>
    </dependency>
    
  • Config-server pom.xml:

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-monitor</artifactId>
        <version>1.3.1.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
        <version>1.2.1.RELEASE</version>
    </dependency>
    

Fault Tolerance Scenario: - Bring down RabbitMQ service/cluster/instance. - All config client looses connectivity. Queues are deleted since they were created as auto-delete. - Bring back up RabbitMQ service.

  • Expectation: All config client should reconnect successfully.

  • Reality: This is not working. Please see below error.

2018-03-27 09:07:12.850 WARN 21251 --- [AO2Q06fYCALSA-6] o.s.a.r.listener.BlockingQueueConsumer : Failed to declare queue:springCloudBus.anonymous.FGZPCPqzTAO2Q06fYCALSA 2018-03-27 09:07:12.851 ERROR 21251 --- [AO2Q06fYCALSA-6] o.s.a.r.l.SimpleMessageListenerContainer : Consumer received fatal exception on startup

org.springframework.amqp.rabbit.listener.QueuesNotAvailableException: Cannot prepare queue for listener. Either the queue doesn't exist or the broker will not allow us to use it. at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:548) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1335) at java.base/java.lang.Thread.run(Thread.java:844) Caused by: org.springframework.amqp.rabbit.listener.BlockingQueueConsumer$DeclarationException: Failed to declare queue(s):[springCloudBus.anonymous.FGZPCPqzTAO2Q06fYCALSA] at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:621) at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:520) [common frames omitted] Caused by: java.io.IOException: null

Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method(reply-code=404, reply-text=NOT_FOUND - no queue 'springCloudBus.anonymous.FGZPCPqzTAO2Q06fYCALSA' in vhost '/', class-id=50, method-id=10)

[common frames omitted] Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method(reply-code=404, reply-text=NOT_FOUND - no queue 'springCloudBus.anonymous.FGZPCPqzTAO2Q06fYCALSA' in vhost '/', class-id=50, method-id=10) at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:505)

[common frames omitted]

2018-03-27 09:07:12.852 ERROR 21251 --- [AO2Q06fYCALSA-6] o.s.a.r.l.SimpleMessageListenerContainer : Stopping container from aborted consumer 2018-03-27 09:07:12.853 INFO 21251 --- [AO2Q06fYCALSA-6] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish. 2018-03-27 09:07:12.853 INFO 21251 --- [AO2Q06fYCALSA-6] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish.

  • Description of error from my understanding config client using the existing broker, listener tried to reconnect but queue is missing. Makes 3 retries by default. This is expected as we are going through a scenario when a Rabbit MQ service is down and restarted without persistent data. Issue is reconnection fails. I know from many articles that mentions we cannot redeclare queue without using admin. For that we create a XML config file that creates property beans declaring admin and other stuff.

What is the ask? - Will it be ideal if all this is taken care as by default scenario. ** Also I still don't have the working solution. NEED HELP"

turbocoder
  • 33
  • 1
  • 8
  • I can't reproduce it, even with the old versions you are using (see my answer). If you can provide a complete (but small) example that exhibits the behavior, I can take a look. – Gary Russell Mar 27 '18 at 17:47

1 Answers1

0

I just tested it with Boot 2.0 and Finchley.M9 (bus 2.0.0.M7) with no problems...

2018-03-27 13:25:06.125 INFO 36716 --- [ main] c.s.b.r.p.RabbitExchangeQueueProvisioner : declaring queue for inbound: springCloudBus.anonymous.tySvAS8BSpS7OtQ_VCeiVQ, bound to: springCloudBus

...

2018-03-27 13:26:38.220 ERROR 36716 --- [ 127.0.0.1:5672] o.s.a.r.c.CachingConnectionFactory : Channel shutdown: connection error; protocol method: #method(reply-code=320, reply-text=CONNECTION_FORCED - broker forced connection closure with reason 'shutdown', class-id=0, method-id=0)

2018-03-27 13:26:58.757 INFO 36716 --- [pS7OtQ_VCeiVQ-6] o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [localhost:5672]

2018-03-27 13:26:58.761 INFO 36716 --- [pS7OtQ_VCeiVQ-6] o.s.a.r.c.CachingConnectionFactory : Created new connection: rabbitConnectionFactory#52c8295b:5/SimpleConnection@74846ead [delegate=amqp://guest@127.0.0.1:5672/, localPort= 49746]

2018-03-27 13:26:58.762 INFO 36716 --- [pS7OtQ_VCeiVQ-6] o.s.amqp.rabbit.core.RabbitAdmin : Auto-declaring a non-durable, auto-delete, or exclusive Queue (springCloudBus.anonymous.tySvAS8BSpS7OtQ_VCeiVQ) durable:false, auto-delete:true, exclusive:true. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.

The RabbitExchangeQueueProvisioner explicitly sets up a RabbitAdmin to re-declare the queue after the connection is re-established.

I'll try with older versions now...

EDIT

Same result with boot 1.5.10 and Edgware.SR3 (bus 1.3.3.RELEASE).

EDIT2

Same result with the 1.3.1 bus starter (brings in 1.2.1 stream rabbit). Works fine.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • I have not added any beans in my application context. I just added config in applciation.properties. I am using all spring context default beans declaration for rabbit stuff. Do I need to create rabbit admin beans or any thing like that ? Can you guide me ? If possible I want to use annotation based configuration of beans instead of XML but any solution is very helpful. – turbocoder Mar 27 '18 at 21:16
  • You don't need an admin bean. It's all handled inside the provisioner. I have no beans either. Like I said, it all works fine for me, so I need to understand why your experience is different. – Gary Russell Mar 27 '18 at 21:53
  • This is what I found after extensive debugging. RabbitExchangeQueueProvisioner doesnt get used once the connection fails since rabbitmq server is down. BlockingQueueConsumer is throwing exception while using a channel to find the queue. What is expected is that it uses rabbit admin to create the queue. Let me ask one thing, in your trial did you delete the queue on rabbit admin or like started a new container of rabbit admin ? – turbocoder Mar 27 '18 at 22:15
  • Deleting the queue on the admin UI is different to losing the connection with the queue auto deleted for that condition.The binder won't recover from an explicit queue deletion. In my test I stopped and started the broker. – Gary Russell Mar 27 '18 at 22:35
  • Its working now. I am using 1.5.10.RELEASE parent spring boot version. I had 1.5.1.RELEASE which either is not compliant version with stream rabbit or It had a bug. Thanks for help Gary. – turbocoder Mar 27 '18 at 22:54