【问题标题】:RabbitMQ Spring Boot application handle broker downRabbitMQ Spring Boot 应用程序处理代理关闭
【发布时间】:2018-04-16 16:53:19
【问题描述】:

我有一个配置为连接到本地 RabbitMQ 代理的 Spring Boot 应用程序。我还配置了FixedBackOff 策略,以便在 3 次尝试不成功后停止重试连接。

编辑 1:@gary-russell 在here 中解释了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;
}

使用此配置,我在控制台中不断收到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

因此应用程序不会启动并继续打印此异常。 即使代理关闭,我如何启动此应用程序?

【问题讨论】:

    标签: spring spring-boot rabbitmq spring-amqp


    【解决方案1】:

    SimpleRabbitListenerContainerFactoryConfigurer 与您在日志中的内容无关。

    容器大约是@RabbitListener - 偶数驱动的消费者,但这里有一个RabbitHealthIndicator,它已经使用了一个RabbitTemplate,它是一个被动调用,因此这里没有应用任何重试。好吧,您可以通过spring.rabbitmq.template.retry 配置属性配置一些重试,但这不会帮助您在UP 与该健康指标保持一致,同时您实际上是DOWN

    【讨论】:

    • 好的,我的问题是应用程序在 RabbitMQ 关闭时没有响应 HTTP 请求,你知道我有什么办法可以克服它并每隔一段时间重新尝试连接到 RabbitMQ 吗?
    【解决方案2】:

    我是这样弄的:

    @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;
        }
    }
    

    使用 BackOffExponencial 类,您的服务器将检查 rabbitMq 是否在线。此服务将在指数时间内检查并且永远不会停止。

    示例:

    10 次尝试的顺序如下:

    请求 # ... 退出

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

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

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

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

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

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-14
      • 1970-01-01
      • 1970-01-01
      • 2021-11-08
      • 2017-07-28
      • 2017-07-02
      • 1970-01-01
      相关资源
      最近更新 更多