![](/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.