簡體   English   中英

spring-kafka:如果我在應用程序中定義記錄生產者,則Kafka使用者不會收到記錄

[英]spring-kafka: Kafka consumer isn't receiving records if I define a record producer in my application

我正在使用Spring和Spring Kafka編寫一個小的PoC。 我的目標是讓生產者和消費者同時寫信(或閱讀)該主題。

我遇到一種奇怪的情況:

  • 生產者正確地產生了記錄(我可以通過Python腳本使用它們)
  • 消費者未收到記錄
  • 但是,如果我從代碼中刪除了生產者並通過另一種方法(例如,使用python腳本)生成了記錄,則消費者可以正確接收記錄。

以下是我的代碼-與文檔示例非常相似。 更確切地說,問題出在以下事實: 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: ...

這是我嘗試未成功的幾件事:

  • 將生產者和使用者配置放在相同的配置類中
  • 在KafkaConsumerConfiguration中更改Bean的名稱(並在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.

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