Транзакционные сообщения о передаче между кластерами kafka с пружиной - PullRequest
0 голосов
/ 26 апреля 2019

У меня есть два кластера кафки.Мне нужно реализовать вид синхронизации между ними с помощью Kafka-Spring.

[cluster A, topic A]  <-- [spring app] --> [cluster B, topic B]

Я создал прослушиватель с аннотацией @Transactional, который отправляет сообщения с помощью kafkaTemplate.Это прекрасно работает, когда есть подключение к обоим кластерам.Когда соединение с целевым кластером потеряно - кажется, что слушатель все еще подтверждает новые сообщения, но они не публикуются.Я попробовал ручное подтверждение на слушателе, отключил автоматическую фиксацию и т. Д., Но, кажется, они не работают так, как я думаю, что они должны ... Когда соединение снова установлено, сообщения никогда не доставляются.Нужна помощь с этим.

    @KafkaListener(topics = "A", containerFactory = "syncLocalListenerFactory")
    public void consumeLocal(@Header(KafkaHeaders.RECEIVED_MESSAGE_KEY) String key, @Payload SyncEvent message, Acknowledgment ack) {
        kafkaSyncRemoteTemplate.send("B", key, message);
        ack.acknowledge();
    }

Я получаю журналы:

2019-04-26 12:11:40.808  WARN 21304 --- [ad | producer-1] org.apache.kafka.clients.NetworkClient   : [Producer clientId=producer-1] Connection to node 1001 could not be established. Broker may not be available.
2019-04-26 12:11:40.828  WARN 21304 --- [ntainer#0-0-C-1] org.apache.kafka.clients.NetworkClient   : [Consumer clientId=consumer-2, groupId=app-sync] Connection to node 1001 could not be established. Broker may not be available.
2019-04-26 12:11:47.829 ERROR 21304 --- [ad | producer-1] o.s.k.support.LoggingProducerListener    : Exception thrown when sending a message with key='...' and payload='...' to topic B:

org.apache.kafka.common.errors.TimeoutException: Expiring 2 record(s) for sync-2: 30002 ms has passed since batch creation plus linger time

2019-04-26 12:11:47.829 ERROR 21304 --- [ad | producer-1] o.s.k.support.LoggingProducerListener    : Exception thrown when sending a message with key='...' and payload='...' to topic B:

org.apache.kafka.common.errors.TimeoutException: Expiring 2 record(s) for sync-2: 30002 ms has passed since batch creation plus linger time

--- edit ---

kafkaProperties здесь по умолчанию свойства kafka-spring прочитаныиз файла application.properties, но в этом случае все они по умолчанию

    @Bean
    public ConsumerFactory<String, SyncEvent> syncLocalConsumerFactory() {
        Map<String, Object> config = kafkaProperties.buildConsumerProperties();

        config.put(ConsumerConfig.GROUP_ID_CONFIG, kafkaProperties.getStreams().getApplicationId() + "-sync");
        config.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        config.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
        config.put(JsonDeserializer.VALUE_DEFAULT_TYPE, SyncEvent.class);
        config.put(JsonDeserializer.TRUSTED_PACKAGES, "app.structures");

        config.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);

        DefaultKafkaConsumerFactory<String, SyncEvent> cf = new DefaultKafkaConsumerFactory<>(config);
        cf.setValueDeserializer(new JsonDeserializer<>(SyncEvent.class, objectMapper));
        return cf;
    }

    @Bean(name = "syncLocalListenerFactory")
    public ConcurrentKafkaListenerContainerFactory<String, SyncEvent> kafkaSyncLocalListenerContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<String, SyncEvent> factory = new ConcurrentKafkaListenerContainerFactory();
        factory.setConsumerFactory(syncLocalConsumerFactory());
        factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
        factory.getContainerProperties().setAckOnError(false);
        factory.setErrorHandler(new SeekToCurrentErrorHandler(0));
        return factory;
    }

1 Ответ

0 голосов
/ 26 апреля 2019

Этот веб-сайт описывает, как установить обработчик ошибок (используя SeekToCurrentErrorHandler), он может помочь вам.Из документации Spring :

SeekToCurrentErrorHandler: обработчик ошибок, который ищет текущее смещение для каждой темы в оставшихся записях.Используется для перемотки разделов после сбоя сообщения, чтобы его можно было воспроизвести.

...