我有一个spring boot kafka应用程序。我的经纪人每隔几天就会被回收一次。旧的经纪人已取消配置,新的经纪人已配置。
我有一个调度程序,它每隔几个小时检查一次代理。我想确保一旦我们有了新的经纪人, 我们应该重新加载所有与Spring Kafka相关的bean。与KafkaAutoConfiguration非常相似,除了我要触发代理值更改并以编程方式加载自动配置。
每当将旧代理替换为新代理时,如何以编程方式调用自动配置?
答案 0 :(得分:9)
您的需求听起来像Spring Cloud中的 Config Server :https://cloud.spring.io/spring-cloud-static/Greenwich.SR2/multi/multi__spring_cloud_config_2.html#_spring_cloud_config_2,其@RefreshScope
功能:https://cloud.spring.io/spring-cloud-static/Greenwich.SR2/multi/multi__spring_cloud_context_application_context_services.html#refresh-scope。
因此,您需要指定自己的bean并用该注释标记它们:
@Bean
@RefreshScope
public ConsumerFactory<?, ?> kafkaConsumerFactory() {
return new DefaultKafkaConsumerFactory<>(this.properties.buildConsumerProperties());
}
@Bean
@RefreshScope
public ProducerFactory<?, ?> kafkaProducerFactory() {
DefaultKafkaProducerFactory<?, ?> factory = new DefaultKafkaProducerFactory<>(
this.properties.buildProducerProperties());
String transactionIdPrefix = this.properties.getProducer().getTransactionIdPrefix();
if (transactionIdPrefix != null) {
factory.setTransactionIdPrefix(transactionIdPrefix);
}
return factory;
}
这两个bean依赖于配置属性来连接到Apache Kafka代理,这确实足够使它们可刷新。每当发生ContextRefreshedEvent
时,这些bean将使用新的配置属性重新初始化。
我认为ConsumerFactory
个使用者(MessageListenerContainer
和KafkaListenerEndpointRegistry
)也必须在该事件上重新启动。关键是MessageListenerContainer
开始了一个长寿的过程,因此出于KafkaConsumer
的目的缓存了一个poll
实例。
所有ProducerFactory
使用者都不需要重新启动。即使KafkaProducer
被缓存在DefaultKafkaProducerFactory
中,它也将在@RefreshScope
阶段被重新初始化。
更新
我不使用配置服务器。我从领事目录服务获得了新主机。
对,我不是说您使用的是Config Server。那只是以相似的方式寻找我。因此,从高处看,我真的会研究Consul目录解决方案的Config Client实现。
尽管如此,您仍然可以发出RefreshEvent
,这将触发所有@RefreshScope
'd bean的重新加载。为此,您需要实现ApplicationEventPublisherAware
并在您从领事馆进行更新时发出该事件。切记:必须重新启动Kafka侦听器容器。为此,您可以收听RefreshScopeRefreshedEvent
,因为您只有对所有@RefreshScope
都刷新后才真正对重启感兴趣。
有关刷新范围的更多信息:https://gist.github.com/dsyer/a43fe5f74427b371519af68c5c4904c7