Надежная доставка сообщений

Извините, мне нужно немного объяснить, прежде чем перейти к проблеме.

Я использую Kafka Client 0.9.0.0 для отправки сообщений в кластер Kafka. Система представляет собой своего рода конвейер, который принимает сообщения от JMS и отправляет их в Kafka. Чтобы обеспечить надежность сообщения, для режима подтверждения JMS задано значение CLIENT_ACKNOWLEDGE, так что, когда сообщение получено и успешно обработано, приложение подтверждает получение сообщения.

Как только сообщение потребляется, оно отправляется в Kafka, и здесь возникает проблема.

Асинхронный:

Я могу использовать асинхронную отправку производителя Kafka с обратным вызовом, и если при отправке сообщения в Kafka произойдет ошибка, будет слишком поздно сообщить потребителю JMS, чтобы он не подтверждал потребление сообщения. Чтобы преодолеть это, единственное, что я придумал, это сохранить сообщения в обратном вызове, если есть исключение, и попытаться отправить сообщения позже. Но я думаю, что это будет слишком много накладных расходов.

Есть ли другой способ справиться с этой ситуацией с помощью асинхронного вызова?

Синхронно:

Используя синхронный вызов, вызывая get() для будущего, возвращаемого Producer.send(), будет выдано исключение, если возникнет какая-либо проблема при отправке сообщения в Kafka, и об этом можно будет сообщить потребителю JMS, чтобы он не подтвердил сообщение и повторите попытку позже.

Очевидно, что это повлияет на производительность, так как это будет блокирующий вызов, а плохая часть заключается в том, что не будет пакетной обработки сообщений, поскольку Kafka будет подтверждать каждое сообщение.

Я склоняюсь к синхронному вызову, потому что не хочу дополнительной настойчивости.

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


person Abdullah Shaikh    schedule 19.09.2016    source источник


Ответы (1)


Асинхронный способ:

Нет другого пути, кроме как упорствовать. У вас есть компромисс для производительности.

Вы получили сообщение от JMS. Подтвердил, что вы его прочитали. При попытке запушить в тему в kafka почему-то не получилось. Вам нужно сделать две вещи, чтобы это было надежным.

  1. Имейте механизм повторной доставки для отправки в kafka в случае сбоя. У вас может быть экспоненциальный механизм повторных попыток, который будет обслуживать периодически возникающие проблемы (например, перебои в работе сети).
  2. Создайте тему ошибки в kafka или JMS, в которую вы отправляете сообщения, если не удалось отправить kafka. Снова используйте тему ошибки в качестве входных данных для вашего пайплайна. Вам нужно будет ограничить потребление из темы ошибки, так как это может перегрузить ваше приложение, если по какой-то причине push-уведомление неоднократно терпит неудачу.

Это сделает его более надежным.

Синхронный способ:

Я не уверен, как вы можете улучшить производительность в этом случае. Если производительность вашего приложения не является проблемой, я предлагаю вам пойти по этому пути, так как это самый быстрый и простой подход.

Я не уверен, что вы имели в виду, говоря об обратном вызове. Если вы имели в виду, что будете хранить сообщения в памяти, это плохая идея, так как вы потеряете сообщения, если приложение по какой-либо причине будет закрыто или остановлено.

person yaswanth    schedule 20.09.2016
comment
Под сохранением обратного вызова я имел в виду сохранение сообщения в каком-либо постоянном хранилище, таком как база данных или другая тема кафки, как вы сказали. - person Abdullah Shaikh; 23.09.2016
comment
Для асинхронного способа важно отметить, что последовательность сообщений больше не гарантируется. - person Mahesh; 04.05.2018