![](/img/trans.png)
[英]Spring-Kafka Consumer Group Coordination for ConcurrentKafkaListenerContainerFactory
[英]spring-kafka: Kafka consumer isn't receiving records if I define a record producer in my application
我正在使用Spring和Spring Kafka編寫一個小的PoC。 我的目標是讓生產者和消費者同時寫信(或閱讀)該主題。
我遇到一種奇怪的情況:
以下是我的代碼-與文檔示例非常相似。 更確切地說,問題出在以下事實: Spring並未創建KafkaConsumerConfiguration中的bean (即,從未調用構造它們的方法)。
KafkaProducerConfiguration.java
@Configuration
public class KafkaProducerConfiguration {
@Bean
public KafkaTemplate<String, String> kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
@Bean
public ProducerFactory<String, String> producerFactory() {
Map<String, Object> props = new HashMap<>();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:32768");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
return new DefaultKafkaProducerFactory<>(props);
}
}
MessageSender.java
@Component
public class MessageSender {
final static private Logger log = Logger.getLogger(MessageSender.class);
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
@PostConstruct
public void onConstruct() throws InterruptedException {
log.info("Sending messages...");
for (int i = 0; i < 100; ++i) {
kafkaTemplate.send("mytopic", "this is a message");
Thread.sleep(1000);
}
kafkaTemplate.flush(); // NOTE: no changes if I move this call in the loop
log.info("Done sending messages");
}
}
KafkaConsumerConfiguration.java
@Configuration
@EnableKafka
public class KafkaConsumerConfiguration {
@Bean
public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory());
return factory;
}
@Bean
public ConsumerFactory<String, String> consumerFactory() {
return new DefaultKafkaConsumerFactory<>(consumerConfigs());
}
@Bean
public Map<String, Object> consumerConfigs() {
Map<String, Object> props = new HashMap<>();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:32768");
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put(ConsumerConfig.GROUP_ID_CONFIG, "my-service");
return props;
}
}
MyMessageListener.java
@Service
public class MyMessageListener {
final static private Logger log = Logger.getLogger(MyMessageListener.class);
@PostConstruct
public void onConstruct() {
log.info("Message listener started");
}
@KafkaListener(topics = "mytopic")
public void onMessageReceived(String message) {
log.info("Got message: "+ message);
}
}
這是應用程序生成的日志,以供參考: https : //pastebin.com/BY783jiL 。 如您所見,沒有創建消費者Bean(否則,將有一個Block ConsumerConfig values: ...
這是我嘗試未成功的幾件事:
MyMessageListener.onMessageReceived
方法上添加注釋屬性containerFactory = "myBeanName"
) KafkaConsumerConfiguration
的名稱更改為其他名稱 KafkaConsumerConfiguration
添加與kafka不相關的@Bean
,以查看是否會創建它(確實如此) 版本:Spring Boot 1.5.9,Spring-Kafka:1.1.7。
我已經把頭發扯了幾個小時了,任何幫助我都感激不盡。
謝謝!
kafkaTemplate.send("mytopic", "this is a message");
您永遠不要開始使用@PostConstruct
方法與外部服務進行交互-您需要等待構建應用程序后再進行操作。
實現SmartLifecyle
,為isAutoStartup
返回true
並將該代碼移動到start()
。
或實現ApplicationListener<ConstextRefreshedEvent>
並在獲取事件時執行發送。
兩種方法都可以確保應用程序已准備就緒。
剛發現問題。 實際上, MessageSender.onConstruct
需要花費大量時間(100秒)來執行,在此期間,它阻止了Spring創建其他bean。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.