簡體   English   中英

Spring Kafka 模板 - 在 Spring 啟動時連接到 Kafka 主題

[英]Spring Kafka Template - Connect to Kafka Topic on Spring Boot Startup

我已經實現了一個基本的 Spring 引導應用程序,它使用 Spring Kafka。 我希望我的制作人在調用第一個.send()之前連接到 Kafka 主題,但我找不到這樣做的方法。 那可能嗎?

日志顯示 KafkaTemplate 僅在我在16:12:44觸發.send方法后連接到 Kafka 主題:

2021-11-24 16:12:12.602  INFO 63930 --- [           main] c.e.k.KafkaProducerExampleApplication    : The following profiles are active: dev
2021-11-24 16:12:13.551  INFO 63930 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2021-11-24 16:12:13.559  INFO 63930 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-11-24 16:12:13.559  INFO 63930 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.53]
2021-11-24 16:12:13.613  INFO 63930 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-11-24 16:12:13.613  INFO 63930 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 974 ms
2021-11-24 16:12:13.989  INFO 63930 --- [           main] pertySourcedRequestMappingHandlerMapping : Mapped URL path [/v2/api-docs] onto method [springfox.documentation.swagger2.web.Swagger2Controller#getDocumentation(String, HttpServletRequest)]
2021-11-24 16:12:14.190  INFO 63930 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2021-11-24 16:12:14.190  INFO 63930 --- [           main] d.s.w.p.DocumentationPluginsBootstrapper : Context refreshed
2021-11-24 16:12:14.207  INFO 63930 --- [           main] d.s.w.p.DocumentationPluginsBootstrapper : Found 1 custom documentation plugin(s)
2021-11-24 16:12:14.239  INFO 63930 --- [           main] s.d.s.w.s.ApiListingReferenceScanner     : Scanning for api listing references
2021-11-24 16:12:14.336  INFO 63930 --- [           main] c.e.k.KafkaProducerExampleApplication    : Started KafkaProducerExampleApplication in 7.055 seconds (JVM running for 7.341)
2021-11-24 16:12:44.550  INFO 63930 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-11-24 16:12:44.550  INFO 63930 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2021-11-24 16:12:44.551  INFO 63930 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
2021-11-24 16:12:44.649  INFO 63930 --- [nio-8080-exec-1] o.a.k.clients.producer.ProducerConfig    : ProducerConfig values: 

關於 Linh Vu 的回答,最好不要在 bean 定義中創建連接——這在應用程序上下文的生命周期中為時過早。

相反,添加一個實現SmartLifecycle的 bean 並在start()中創建連接; 這樣,上下文將在連接之前完全初始化。

@Bean
SmartLifecycle connector(ProducerFactory<Object ,Object> pf) {
    return new SmartLifecycle() {
        
        @Override
        public void stop() {
        }
        
        @Override
        public void start() {
            pf.createProducer().close();
        }
        
        @Override
        public boolean isRunning() {
            return false;
        }
        
    };
}

使用non-transactional producer (未提供transactionIdPrefix),當您第一次調用KafkaTemplate.send 時,它將委托給ProducerFactory以獲取Producer單個實例 這個時候,因為之前沒有一個ProducerFactory實例Producer會為你創建這個(這就是你看到日志ProducerConfig: ProducerConfig values...的原因)。 這個生產者實例現在被所有客戶端使用/共享。


所以如果你想預先創建上面的生產者實例,你可以直接在ProducerFactory上調用它,例如:

@Bean
public KafkaTemplate<?, ?> kafkaTemplate(ProducerFactory<Object, Object> kafkaProducerFactory) {
        KafkaTemplate<Object, Object> kafkaTemplate = new KafkaTemplate(kafkaProducerFactory);
        kafkaProducerFactory.createProducer();
        return kafkaTemplate;
...

SmartLifecycle bean 為我們工作,謝謝。

@Component
class KafkaProducer (
    private val userChangeLogTemplate: KafkaTemplate<String, UserChangeLog>
    private val kafkaProperties: MizenKafkaProperties
) : NotificationProducer{

    @Bean
    fun connector(pf: ProducerFactory<String, Any>): SmartLifecycle {
        return object : SmartLifecycle {
            override fun stop() {}
            override fun start() {
                pf.createProducer().close()
            }

            override fun isRunning(): Boolean {
                return false
            }
        }
    }

    override fun sendUserChangeLog(message: UserChangeLog) {
        userChangeLogTemplate.send(kafkaProperties.userChangeLogTopic, message)
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM