【问题标题】:Enforce Spring Boot Application to Fail When Cannot Connect to Kafka无法连接到 Kafka 时强制 Spring Boot 应用程序失败
【发布时间】:2019-08-06 05:51:18
【问题描述】:

如果我的 Spring Boot 应用程序无法连接到 kafka 代理,我想让它在启动时失败。我的应用程序仅将消息发布到主题。我将此行添加到我的属性文件中,但到目前为止没有运气spring.kafka.admin.fail-fast=true

【问题讨论】:

    标签: spring spring-boot apache-kafka kafka-producer-api spring-kafka


    【解决方案1】:

    关于如何加快 fail-fast 的补充

    TL;DR Spring Boot 2.4.5 自动配置不允许您使用 env 参数加速快速失败。将此添加到您的 @Configuration 以获得 10 秒超时:

    @Bean
    public KafkaAdmin kafkaAdmin(@Autowired KafkaProperties properties) {
        KafkaAdmin kafkaAdmin = new KafkaAdmin(properties.buildAdminProperties());
        kafkaAdmin.setFatalIfBrokerNotAvailable(properties.getAdmin().isFailFast());
    
        /* speed up fail fast */
        kafkaAdmin.setOperationTimeout(5);
        kafkaAdmin.setCloseTimeout(5);
    
        return kafkaAdmin;
    }
    

    更详细的答案

    在执行org.springframework.kafka.core.KafkaAdmin 类的initialize() 方法时发生快速失败。此方法可能会阻塞:

    1. 如果发现新主题,它将阻止主题创建最多 operationTimeout
      1. 如果主题创建失败,它会阻止释放资源最多closeTimeout

    默认情况下,这些值相应地是 30 和 10 秒(在上面提到的类中硬编码)。您可以使用 set 方法重新定义它们:setOperationTimeout(int sec)setCloseTimeout(int sec)

    Spring Boot 呢? KafkaAdmin bean 在类 org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration 中创建。可以猜到,Spring Boot 根本不设置超时:

    @Bean
    @ConditionalOnMissingBean
    public KafkaAdmin kafkaAdmin() {
        KafkaAdmin kafkaAdmin = new KafkaAdmin(this.properties.buildAdminProperties());
        kafkaAdmin.setFatalIfBrokerNotAvailable(this.properties.getAdmin().isFailFast());
        return kafkaAdmin;
    }
    

    【讨论】:

      【解决方案2】:

      fail-fast 仅在上下文中至少有一个 NewTopic bean 时才有效(因此管理员将尝试检查主题是否存在,如果不存在则创建它)。

      @SpringBootApplication
      public class So55177700Application {
      
          public static void main(String[] args) {
              SpringApplication.run(So55177700Application.class, args);
          }
      
          @Bean
          public NewTopic topic() {
              return new NewTopic("so55177700", 1, (short) 1);
          }
      
      }
      
      Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
      2019-03-15 09:42:49.555 ERROR 41793 --- [           main] o.s.boot.SpringApplication               : Application run failed
      
      java.lang.IllegalStateException: Could not configure topics
      

      【讨论】:

      • 感谢您的回答。所以这将从正在运行的应用程序创建主题。如果我消费一个主题,我需要的是类似的行为。在这种情况下,应用程序将失败,因为带有 KafkaListener 注释的方法将尝试连接 kafka 代理并使用消息。
      • 消费者在与启动应用程序的线程不同的线程上运行。添加主题 bean 是唯一的开箱即用的机制来做你想做的事。您可以编写自己的Lifecycle bean,连接到start() 中的代理。但是我不确定您为什么要这样做,因为您的消费者无论如何都需要该主题。而且,如果主题已经存在,则什么都不会做,管理员只是检查它的存在。
      • 能不能做到fail-faster?在我的情况下,应用程序在失败前花费了大约 40 秒(强制 I/O 线程关闭),尽管它比没有 fail-fast 功能的大约 2 分钟 40 秒要好得多。
      • 最好提出一个新问题,而不是评论一个旧答案。人们更容易找到答案。一定要在新问题中引用答案。您可以尝试减少 kafka 管理客户端属性 request.timeout.ms 的默认值(30 秒)。使用 Boot,它是 spring.kafka.admin.properties.request.timeout.ms=5000
      猜你喜欢
      • 2020-06-25
      • 2021-11-10
      • 1970-01-01
      • 2020-01-21
      • 1970-01-01
      • 2019-08-25
      • 2020-03-22
      • 2020-06-16
      • 1970-01-01
      相关资源
      最近更新 更多