如何以编程方式自动配置?

时间:2019-07-05 12:16:23

标签: java spring spring-boot spring-kafka

我有一个spring boot kafka应用程序。我的经纪人每隔几天就会被回收一次。旧的经纪人已取消配置,新的经纪人已配置。

我有一个调度程序,它每隔几个小时检查一次代理。我想确保一旦我们有了新的经纪人, 我们应该重新加载所有与Spring Kafka相关的bean。与KafkaAutoConfiguration非常相似,除了我要触发代理值更改并以编程方式加载自动配置。

每当将旧代理替换为新代理时,如何以编程方式调用自动配置?

1 个答案:

答案 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个使用者(MessageListenerContainerKafkaListenerEndpointRegistry)也必须在该事件上重新启动。关键是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