【发布时间】: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
如果我的 Spring Boot 应用程序无法连接到 kafka 代理,我想让它在启动时失败。我的应用程序仅将消息发布到主题。我将此行添加到我的属性文件中,但到目前为止没有运气spring.kafka.admin.fail-fast=true。
【问题讨论】:
标签: spring spring-boot apache-kafka kafka-producer-api spring-kafka
关于如何加快 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() 方法时发生快速失败。此方法可能会阻塞:
operationTimeout
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;
}
【讨论】:
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 代理并使用消息。
Lifecycle bean,连接到start() 中的代理。但是我不确定您为什么要这样做,因为您的消费者无论如何都需要该主题。而且,如果主题已经存在,则什么都不会做,管理员只是检查它的存在。
fail-faster?在我的情况下,应用程序在失败前花费了大约 40 秒(强制 I/O 线程关闭),尽管它比没有 fail-fast 功能的大约 2 分钟 40 秒要好得多。
request.timeout.ms 的默认值(30 秒)。使用 Boot,它是 spring.kafka.admin.properties.request.timeout.ms=5000