我有read the documentation about receiving messages:
您可以通过配置MessageListenerContainer并提供消息侦听器或使用@KafkaListener批注来接收消息。
但是我无法完全正常工作。我使用的是Spring Boot 2.1.2,并且可能对Bean造成的危害大于对我的好处,因此可能会使Soup的盐含量过高,所以我想了解它的工作原理,因此我可以检查我偏离了哪里荣耀之路。
如果我正确地理解了文档,那么配置MessageListenerContainer
就足够了,例如这个在这里:
@Configuration
public class MyKafkaConfiguration {
@Bean
public MessageListenerContainer myVeryOwnListener(ConsumerFactory<String, String> consumerFactory) {
ContainerProperties cProps = new ContainerProperties(new TopicPartitionInitialOffset("spring-kafka-stackoverflow-questions", /* partition */ 0, /* Offset */ 0L));
KafkaMessageListenerContainer<String, String> result = new KafkaMessageListenerContainer<>(consumerFactory, cProps);
result.setupMessageListener(MessageListener<String, String) System.out::println);
return result;
}
}
这将毫无例外地启动,但实际上似乎并未监听代理上的任何消息。
从我从带注释的通常流程中获得的信息来看,需要有人以KafkaListenerEndpoint
到KafkaListenerEndpointRegistry
的形式注册侦听器。
KafkaListenerAnnotationBeanPostPorcessor
会自动对@KafkaListener
注释的所有方法执行此操作,但是在我想采用路径的情况下,这应该如何工作
通过配置MessageListenerContainer并提供消息侦听器
代替
使用@KafkaListener批注
我不太明白。此外,KafkaAutoConfiguration
中没有任何方法(Spring Boot提供),例如使用List<MessageListenerContainer>
并自动将它们全部注册到注册表中,因此这并不奇怪。
但是,正如文档所建议的,它首先应该如何工作?我误会了那部分吗? 有人可以启发我吗?
答案 0 :(得分:2)
该文档的下一部分说:
使用消息侦听器容器时,必须提供一个侦听器以接收数据。当前有八个支持的消息侦听器接口。以下清单显示了这些接口
然后有一个节Using KafkaMessageListenerContainer
:
要将
MessageListener
分配给容器,可以在创建容器时使用ContainerProps.setMessageListener
方法。以下示例显示了如何执行此操作:ContainerProperties containerProps = new ContainerProperties("topic1", "topic2"); containerProps.setMessageListener(new MessageListener<Integer, String>() { ... }); DefaultKafkaConsumerFactory<Integer, String> cf = new DefaultKafkaConsumerFactory<Integer, String>(consumerProps()); KafkaMessageListenerContainer<Integer, String> container = new KafkaMessageListenerContainer<>(cf, containerProps); return container;
该参考文献的开头有一个完整的示例:https://docs.spring.io/spring-kafka/docs/2.2.8.RELEASE/reference/html/#a-very-very-quick-example
@Test
public void testAutoCommit() throws Exception {
logger.info("Start auto");
ContainerProperties containerProps = new ContainerProperties("topic1", "topic2");
final CountDownLatch latch = new CountDownLatch(4);
containerProps.setMessageListener(new MessageListener<Integer, String>() {
@Override
public void onMessage(ConsumerRecord<Integer, String> message) {
logger.info("received: " + message);
latch.countDown();
}
});
KafkaMessageListenerContainer<Integer, String> container = createContainer(containerProps);
container.setBeanName("testAuto");
container.start();
Thread.sleep(1000); // wait a bit for the container to start
KafkaTemplate<Integer, String> template = createTemplate();
template.setDefaultTopic(topic1);
template.sendDefault(0, "foo");
template.sendDefault(2, "bar");
template.sendDefault(0, "baz");
template.sendDefault(2, "qux");
template.flush();
assertTrue(latch.await(60, TimeUnit.SECONDS));
container.stop();
logger.info("Stop auto");
}
答案 1 :(得分:1)
我刚刚将您的bean复制到了新的启动应用程序中,并且工作正常。
端点注册表仅适用于@KafkaListener
容器,因为它们没有在应用程序上下文中注册为bean(注册表是bean)。
@SpringBootApplication
public class So57628247Application {
private static final int MessageListener = 0;
public static void main(String[] args) {
SpringApplication.run(So57628247Application.class, args);
}
@Bean
public MessageListenerContainer myVeryOwnListener(ConsumerFactory<String, String> consumerFactory) {
ContainerProperties cProps = new ContainerProperties(new TopicPartitionInitialOffset(
"spring-kafka-stackoverflow-questions", /* partition */ 0, /* Offset */ 0L));
KafkaMessageListenerContainer<String, String> result = new KafkaMessageListenerContainer<>(consumerFactory,
cProps);
result.setupMessageListener((MessageListener<String, String>) System.out::println);
return result;
}
@Bean
public NewTopic topic() {
return new NewTopic("spring-kafka-stackoverflow-questions", 1, (short) 1);
}
@Bean
public ApplicationRunner runner(KafkaTemplate<String, String> template) {
return args -> {
template.send("spring-kafka-stackoverflow-questions", "foo");
};
}
}
和
ConsumerRecord(主题= spring-kafka-stackoverflow-questions,分区= 0,偏移量= 0,CreateTime = 1566573407373,序列化密钥大小= -1,序列化值大小= 3,标头= RecordHeaders(标头= [],isReadOnly = false),键= null,值= foo)