简体   繁体   English

RabbitMQ Spring Boot 应用程序处理代理关闭

[英]RabbitMQ Spring Boot application handle broker down

I have a Spring Boot application configured to connect to a local RabbitMQ broker.我有一个 Spring Boot 应用程序配置为连接到本地 RabbitMQ 代理。 I have also configured a FixedBackOff strategy in order to stop retrying connecting after 3 unsuccessful attempts.我还配置了FixedBackOff策略,以便在 3 次尝试失败后停止重试连接。

EDIT 1: I have the following configuration for FixedBackOff as explained by @gary-russell in here :编辑 1:如@gary-russell 在此处解释的那样,我对FixedBackOff进行了以下配置:

@Bean(name = "rabbitListenerContainerFactory")
public SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory(
        SimpleRabbitListenerContainerFactoryConfigurer configurer,
        ConnectionFactory connectionFactory) {
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    configurer.configure(factory, connectionFactory);
    BackOff recoveryBackOff = new FixedBackOff(5000, 3);
    factory.setRecoveryBackOff(recoveryBackOff);
    return factory;
}

With this configuration, I keep getting a ConnectionException in the console:使用此配置,我不断在控制台中收到ConnectionException

2018-04-16 13:48:29.769  WARN 54952 --- [nfoReplicator-0] o.s.b.a.health.RabbitHealthIndicator     : Health check failed

org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused
    at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:62)
    at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:368)
    at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:573)
    at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1430)
    at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1411)
    at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1387)
    at org.springframework.boot.actuate.health.RabbitHealthIndicator.getVersion(RabbitHealthIndicator.java:49)
    at org.springframework.boot.actuate.health.RabbitHealthIndicator.doHealthCheck(RabbitHealthIndicator.java:45)
    at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.java:43)
    at org.springframework.boot.actuate.health.CompositeHealthIndicator.health(CompositeHealthIndicator.java:68)
    at org.springframework.cloud.netflix.eureka.EurekaHealthCheckHandler.getHealthStatus(EurekaHealthCheckHandler.java:103)
    at org.springframework.cloud.netflix.eureka.EurekaHealthCheckHandler.getStatus(EurekaHealthCheckHandler.java:99)
    at com.netflix.discovery.DiscoveryClient.refreshInstanceInfo(DiscoveryClient.java:1362)
    at com.netflix.discovery.InstanceInfoReplicator.run(InstanceInfoReplicator.java:100)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.ConnectException: Connection refused
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at com.rabbitmq.client.impl.SocketFrameHandlerFactory.create(SocketFrameHandlerFactory.java:50)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:907)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:859)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:799)
    at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:352)
    ... 19 common frames omitted

Therefore the application does not go up and keeps on printing this exception.因此应用程序不会启动并继续打印此异常。 How can I start this application even when the broker is down?即使代理关闭,我如何启动此应用程序?

That SimpleRabbitListenerContainerFactoryConfigurer is not related to what you have in the logs. SimpleRabbitListenerContainerFactoryConfigurer与您在日志中的内容无关。

The container is about @RabbitListener - even-driven consumers, but here you have a RabbitHealthIndicator which uses already a RabbitTemplate and it is a passive call, therefore no any retry is applied here.该容器是关于@RabbitListener - 偶数驱动的消费者,但这里有一个RabbitHealthIndicator它已经使用了一个RabbitTemplate并且它是一个被动调用,因此这里没有应用任何重试。 Well, you can configure some retry via spring.rabbitmq.template.retry configuration properties, but that won't help you to stay UP with that health indicator meanwhile you are really DOWN .好吧,您可以通过spring.rabbitmq.template.retry配置属性配置一些重试,但这不会帮助您保持UP与该健康指标同时您真的DOWN

I made this way:我是这样做的:

@Configuration
@EnableRabbit
public class AmqpConfiguration {

    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        ExponentialBackOff recoveryBackOff = new ExponentialBackOff();
        factory.setRecoveryBackOff(recoveryBackOff);
        return factory;
    }
}

Using the BackOffExponencial class, your server will check whether rabbitMq is online.使用 BackOffExponencial 类,您的服务器将检查 rabbitMq 是否在线。 This service will check in exponential time and it will never stop.该服务将在指数时间内进行检查,并且永远不会停止。

Exemple:例子:

For 10 attempts the sequence will be as follows:对于 10 次尝试,顺序如下:

request # ... back off请求 # ... 退出

1 ................. 2000 1 ................... 2000

2 ................. 3000 2 ................... 3000

3 ................. 4500 3 ................... 4500

4 ................. 6750 4 ...................... 6750

5 ................. 10125 5 ..................... 10125

6 ................. 15187 6 ..................... 15187

7 ................. 22780 7 ...................... 22780

8 ................. 30000 8 ................... 30000

9 ................. 30000 9 ..... 30000

10 ................. 30000 10 ...... 30000

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM