request.timeout.ms и синхронная публикация событий Spring Kafka с помощью KafkaTemplate - PullRequest
0 голосов
/ 10 июня 2019

Я немного озадачен рекомендациями по настройке тайм-аута события, публикуемого синхронно через Spring Kafka. В документации Spring Kafka приведен пример использования ListenableFuture get(SOME_TIME, TimeUnit) для включения синхронная публикация событий с таймаутом SOME_TIME. (дублируется ниже для справки).

public void sendToKafka(final MyOutputData data) {
    final ProducerRecord<String, String> record = createRecord(data);

    try {
        template.send(record).get(10, TimeUnit.SECONDS);
        handleSuccess(data);
    }
    catch (ExecutionException e) {
        handleFailure(data, record, e.getCause());
    }
    catch (TimeoutException | InterruptedException e) {
        handleFailure(data, record, e);
    }
}

С другой стороны, я посмотрел Документация по конфигурации производителя Kafka и увидел, что у Kafka была конфигурация для request.timeout.ms, которая отвечала за настройку ниже в Kafka.

Конфигурация контролирует максимальное количество времени, которое клиент будет ожидать ответа на запрос. Если ответ не получен до истечения времени ожидания, клиент при необходимости повторно отправит запрос или не выполнит запрос, если повторные попытки исчерпаны.

Будет ли разумнее настроить template.send(...).get(...) с некоторой единицей времени (например, 10 секунд / 10000 мс, как указано в примере из Spring Kafka выше), или лучше будет настроить request.timeout.ms (вдоль с retries), чтобы эмулировать это поведение внутри Kafka и сделать вызов без аргументов к get()?

1 Ответ

1 голос
/ 10 июня 2019

Никогда не стоит использовать no-args get();Вы могли бы зависнуть навсегда, если бы была какая-то ошибка в клиентском коде.

Два тайм-аута действительно разные.

Будущее get() - получить результат отправки (успех или неудача).).

Если ваша конфигурация производителя может быть успешной после истечения времени ожидания get(), вы можете получить дубликаты (при условии, что вы пытаетесь повторить попытку на уровне приложения после сбоя).

Я полагаю, что "лучшийпрактика "будет заключаться в использовании get() тайм-аута, который больше retries * request.timeout.ms, но это может занять много времени.Но это гарантирует, что вы получите реальный результат отправки.Получение тайм-аута в такой ситуации следует рассматривать как аномалию, требующую расследования.

...