springcloud stream 報錯 Rabbit health check failed


問題現象

在使用SpringCloud Stream集成RabbitMQ的時候報了這個錯:

2021-08-06 21:34:05.153  WARN 18660 --- [-172.28.165.129] o.s.b.a.amqp.RabbitHealthIndicator       : Rabbit health check failed
org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused: connect

一開始我被Connection refused: connect迷惑了,查了半天為啥連不上RabbitMQ。翻源碼、debug發現連接的地址沒錯,看RabbitMQ控制台也有connection和channel,說明實際還是連上了。

那為啥還報這個錯呢?

仔細一看拋異常的是RabbitHealthIndicator,原來是SpringBoot Actuator想要監控RabbitMQ的連接狀態,但是連接被拒絕。

我的配置文件如下:

spring:
  cloud:
    stream:
      binders: # 在此處配置要綁定的rabbitmq的服務信息;
        defaultRabbit: # 表示定義的名稱,用於於binding整合
          type: rabbit # 消息組件類型
          inheritEnvironment: false
          environment: # 設置rabbitmq的相關的環境配置
            spring:
              rabbitmq:
                host: 172.22.234.51
                port: 5672
                username: admin
                password: 123

原因

就是因為我使用了spring.cloud.stream.binders.*.environment屬性配置rabbitMQ的相關信息,但是沒配置spring.rabbitmq。這就導致自動配置檢測到類路徑下有rabbit相關的類,就配置了rabbit相關的Bean。

其中org.springframework.boot.actuate.amqp.RabbitHealthIndicator負責監控rabbit的連接狀況,通過下面這個配置類自動配置。

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RabbitTemplate.class)
@ConditionalOnBean(RabbitTemplate.class)
@ConditionalOnEnabledHealthIndicator("rabbit")
@AutoConfigureAfter(RabbitAutoConfiguration.class)
public class RabbitHealthContributorAutoConfiguration
      extends CompositeHealthContributorConfiguration<RabbitHealthIndicator, RabbitTemplate> {

   @Bean
   @ConditionalOnMissingBean(name = { "rabbitHealthIndicator", "rabbitHealthContributor" })
   public HealthContributor rabbitHealthContributor(Map<String, RabbitTemplate> rabbitTemplates) {
      return createContributor(rabbitTemplates);
   }

}

但是沒有檢測到spring.rabbitmq相關的配置,就使用了默認的配置,嘗試連接localhost:5672,然后就出現了org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused: connect

問題的關鍵在於,spring.cloud.stream.binders.*.environment為每個binder創建了單獨的上下文環境,跟application context是完全隔離的。所以,僅僅配置了spring.cloud.stream.binders.*.environment,使Actuator從application context中沒有找到rabbitmq的配置。

參考Spring Cloud Stream and RabbitMQ health check

解決方法

  1. RabbitHealthIndicator需要spring.rabbitmq的配置,就給他:將spring.cloud.stream.binders.*.environment里面的配置拿到spring.rabbitmq中。

  2. 禁用RabbitHealthIndicator。上面提到的配置類上還有一個@ConditionalOnEnabledHealthIndicator("rabbit"),意思就是:配置management.health.rabbit.enabled為true的時候生效。禁用即可解決。

    management:
      health:
        rabbit:
          enabled: true
    
  3. 在localhost安裝一個RabbitMQ(開玩笑的)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM