简体   繁体   中英

How to launch kafka consumer before producer

I have a banch of microservices interacting with kafka topic. One of the microservice should consume two integers and after that sum them and send to the topic. The problem is that I cannot configure microservice so that consumer to be launched before the producer. My code is as follows:

@SpringBootApplication
public class AdderApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(AdderApplication.class, args);
        AdderConsumer consumer = context.getBean(AdderConsumer.class);
        AdderProducer producer = context.getBean(AdderProducer.class);

        producer.sumTwoIntegers();
    }
@Component
public class AdderConsumer extends Controller {

    private CountDownLatch latch = new CountDownLatch(3);

    @KafkaListener(topics = "${kafka.topic.name}")
    public void listenToPartitionWithOffset(@Payload Integer message) {
        if (message != null) {
            list.add(message);
            isProduce = true;
            System.out.println(list);
        }   
    }
@Component
public class AdderProducer extends Controller {

    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    @Value("${kafka.topic.name}")
    private String topicName;


    public void sumTwoIntegers() {
       // logic
    }

    private void sendMessage(String message) {
        // logic
    }
@Configuration
@EnableKafka
public class KafkaConfig {

    @Value("${kafka.boot.server}")
    private String kafkaServer;

    @Value("${kafka.consumer.group.id}")
    private String kafkaGroupId;

    @Bean
    public LoggingErrorHandler errorHandler(){
        return new LoggingErrorHandler();
    }

    @Bean
    public KafkaTemplate<String, String> kafkaTemplate() {
        return new KafkaTemplate<>(producerConfig());
    }

    @Bean
    public ProducerFactory<String, String> producerConfig() {
        Map<String, Object> config = new HashMap<>();
        config.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaServer);
        config.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        config.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);

        return new DefaultKafkaProducerFactory<>(config);
    }

    @Bean
    public ConsumerFactory<String, Integer> consumerConfig() {
        Map<String, Object> config = new HashMap<>();
        config.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaServer);
        config.put(ConsumerConfig.GROUP_ID_CONFIG, kafkaGroupId);
        config.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        config.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, IntegerDeserializer.class);

        return new DefaultKafkaConsumerFactory<>(config);
    }

    @Bean
    public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, Integer>> kafkaListenerContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<String, Integer> listener = new ConcurrentKafkaListenerContainerFactory<>();
        listener.setConsumerFactory(consumerConfig());
        listener.setErrorHandler(errorHandler());
        return listener;
    }

I debugged the code and it calls both producer and listener, however I need listener to receive both integers first and only after that to call producer method.

I will appreciate your thoughts.

I found the decision. I implemented timer for producer and it periodically invoked when application is running. So when it invokes for the firs time with no data to process it posts nothing, then customer consumes data and the second invocation of producer posts the necessary data to the topic.

THe other solution is to call producer method from consumer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM