Гарантии доставки



Вспомним проблему из прошлого поста.



Мы отправили запрос, соединение тут же пропало и восстановилось через 3 секунды. Что делать с запросом?



Если запрос идемпотентный, спокойно повторяем отправку.



А если нет?



Тогда выбираем одну из трёх стратегий: at least once, at most once или exactly once.



Вообще эти термины используются для месседж брокеров и доставки сообщений, но те же принципы верны для HTTP запросов и любого взаимодействия.



В чём суть:



1️⃣ At most once



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



2️⃣ At least once



В процесс общения добавляется 1 шаг — уведомление о получении. Отправитель повторяет запрос, пока не получит уведомление.



Сообщение точно будет доставлено

Может быть доставлено несколько раз



3️⃣ Exactly once



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



Общая схема простая. У каждого сообщения есть ID. Получатель ведёт список полученных ID и для каждого сообщения

▫️ Отправляет уведомление о получении

▫️ Проверяет, не приходило ли такое сообщение раньше. Если да — отбрасывает его, если нет — обрабатывает



Выглядит легко, но в распределённых системах задача усложняется. Что угодно может отвалиться, данные нужно реплицировать, адреса постоянно меняются и тд. В Kafka гарантия exactly once появилась только в 2017 году, и документ с дизайном занимает 67 страниц.



Что делать с этим знанием?



Узнать, какая стратегия используется на вашем проекте, и есть ли дополнительные требования к коду. Для разработчика этого достаточно, обычно все заботы о гарантиях берут на себя архитекторы🤓



Что почитать о сложностях exactly-once в распределённых системах?

▫️ Семантика exactly-once в Apache Kafka

▫️ Подробный разбор проблем на примере очереди Amazon (англ)

▫️ Сборник статей про exactly-once (англ)