Что происходит при передаче данных между сервисами с брокером сообщений если сервис недоступен
Что проверяют
Понимаете ли вы, что брокер ставят именно для этого: отправитель не знает и не должен знать, жив ли получатель. Дальше смотрят, где в такой схеме сообщения всё равно теряются.
Как отвечать
Начать с разделения: недоступен потребитель или недоступен сам брокер.
Если лёг потребитель, отправитель этого не замечает. В RabbitMQ сообщения копятся в очереди, и при устойчивой очереди с постоянными сообщениями переживают перезапуск брокера. В Kafka сообщение пишется в лог и живёт по времени хранения независимо от того, читал его кто-нибудь или нет, потребитель просто вернётся к своему смещению. Когда сервис поднимается, он разбирает накопленное, и здесь важно, выдержит ли он всплеск и уложится ли в таймауты.
Если недоступен брокер, проблема у отправителя: запись в базу прошла, а событие не ушло. Отсюда паттерн transactional outbox, когда событие пишется в ту же базу той же транзакцией, а отдельный процесс публикует его позже.
Что назвать дальше:
- подтверждения с обеих сторон: подтверждения публикации у продюсера, ручной ack у потребителя после обработки, а не до неё;
- повторы с растущей выдержкой и очередь недоставленных сообщений, чтобы одно ядовитое сообщение не блокировало остальные;
- доставка почти всегда at least once, поэтому обработчик обязан быть идемпотентным по ключу сообщения;
- мониторинг отставания и глубины очереди: это первый признак, что получателю плохо.
Где спотыкаются
Обещают гарантированную доставку и на этом заканчивают. Гарантия у брокера настраиваемая: без постоянных сообщений и устойчивой очереди RabbitMQ теряет её при перезапуске, а продюсер Kafka без ожидания подтверждений теряет пакет молча.
Второе: забывают про дубликаты. Повтор при неполученном подтверждении создаст второе списание, если у потребителя нет проверки по идентификатору сообщения. Идемпотентность тут не украшение, а условие работы схемы.
Третье: считают, что копить можно бесконечно. Очередь упирается в диск и лимиты, а записи в Kafka пропадают по истечении срока хранения. Недоступность длиной в сутки без алертов заканчивается потерянными событиями.