Перейти к основному содержимому
Нормативная версия документации - английская

Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.

Завершение

Чем ack, drop, retry и retry_after становятся в Pulsar: подтверждениями и повторными доставками, которые брокер засчитывает в политику dead-letter клиента.

Каждый исход обработчика в Pulsar: о чём крейт просит клиент и что делает брокерОбработчикКрейт вызываетБрокерack()ack_with_idподтверждено,больше неприходитretry()nack_with_idприходит сновасразу,счётчик + 1retry_after(d)ждёт d, затемnack_with_idприходит сновачерез d,счётчик + 1drop()ack_with_idподтверждено:удаленонет исходаничего; позжесработаеттаймер клиентаснова черезack_timeout,счётчик + 1Счётчик растёт только у подписок Shared и KeyShared:у остальных типов его нет
Схема текстом
  1. Обработчик: ack(); retry(); retry_after(d); drop(); нет исхода
  2. Крейт вызывает: ack_with_id; nack_with_id; ждёт d, затем nack_with_id; ack_with_id; ничего; позже сработает таймер клиента; Счётчик растёт только у подписок Shared и KeyShared: у остальных типов его нет
  3. Брокер: подтверждено, больше не приходит; приходит снова сразу, счётчик + 1; приходит снова через d, счётчик + 1; подтверждено: удалено; снова через ack_timeout, счётчик + 1
  4. ack() → ack_with_id
  5. ack_with_id → подтверждено, больше не приходит
  6. retry() → nack_with_id
  7. nack_with_id → приходит снова сразу, счётчик + 1
  8. retry_after(d) → ждёт d, затем nack_with_id
  9. ждёт d, затем nack_with_id → приходит снова через d, счётчик + 1
  10. drop() → ack_with_id
  11. ack_with_id → подтверждено: удалено
  12. нет исхода → ничего; позже сработает таймер клиента
  13. ничего; позже сработает таймер клиента → снова через ack_timeout, счётчик + 1

Каждый исход - это вызов консьюмера клиента, который принадлежит подписке. Вызов делает её управляющая задача. ack и drop подтверждают сообщение, потому что в Pulsar нет команды, которая отвергает сообщение окончательно: сообщение, которое не должно вернуться, подтверждается, а сообщение, которое раз за разом не обрабатывается, по достижении предела попадает в топик dead-letter. retry просит брокер сразу доставить сообщение снова.

retry_after(d) держит доставку в сервисе неподтверждённой в течение d, а затем отправляет то же отрицательное подтверждение. Ожидание идёт на том рантайме, где подключился брокер. Задержка не короче ack_timeout подписки отвергается, потому что таймер клиента вернул бы сообщение раньше.

Доставка, которую не завершил ни один обработчик, остаётся неподтверждённой. Если задан ack_timeout, клиент запрашивает её снова, когда тайм-аут истекает, как показывает страница Подтверждение. Если не задан, она возвращается только после отключения консьюмера.

Повторы​

Повтор в Pulsar: отрицательное подтверждение сразу или после ожидания, повторная доставка брокером и предел клиентаДоставкаброкер считает её повторные доставкиОбработчик возвращаетretry() или retry_after(d)retry():отрицательноеподтверждение сразуretry_after(d): ждёт dв процессе,затем то жеБрокер доставляет её сновасчётчик + 1Политика dead-letter клиента:достиг ли счётчик max_attempts?Ниже предела:обработчикполучает её сноваНа пределе: копияв топик dead-letter,оригинал подтверждёнПредел на подписке Exclusive или Failoverне даёт запуститься: они не считают повторные доставкиОстановка во время ожидания теряет его, а не сообщение:сообщение остаётся неподтверждённым
Схема текстом
  1. Доставка брокер считает её повторные доставки → Обработчик возвращает retry() или retry_after(d): обработано
  2. Обработчик возвращает retry() или retry_after(d) → retry(): отрицательное подтверждение сразу
  3. Обработчик возвращает retry() или retry_after(d) → retry_after(d): ждёт d в процессе, затем то же
  4. retry(): отрицательное подтверждение сразу → Брокер доставляет её снова счётчик + 1
  5. retry_after(d): ждёт d в процессе, затем то же → Брокер доставляет её снова счётчик + 1
  6. Брокер доставляет её снова счётчик + 1 → Политика dead-letter клиента: достиг ли счётчик max_attempts?
  7. Политика dead-letter клиента: достиг ли счётчик max_attempts? → Ниже предела: обработчик получает её снова: ниже
  8. Политика dead-letter клиента: достиг ли счётчик max_attempts? → На пределе: копия в топик dead-letter, оригинал подтверждён: на пределе
  9. Предел на подписке Exclusive или Failover не даёт запуститься: они не считают повторные доставки
  10. Остановка во время ожидания теряет его, а не сообщение: сообщение остаётся неподтверждённым

Чтобы вернуть сообщение, ничего не публикуется: брокер снова доставляет то же сообщение и засчитывает доставку. max_attempts и топик dead-letter, которые объявляет регистрация, становятся политикой dead-letter клиента. Клиент отдаёт сообщение, пока его счётчик ниже предела, поэтому обработчик видит его max_attempts раз. На пределе клиент отправляет сообщение в топик dead-letter и подтверждает оригинал.

Эти две настройки задаются вместе. Регистрация, которая объявляет одну без другой, не запускается. Не запускается и предел на подписке Exclusive или Failover: её сообщения всегда приходят со счётчиком, равным нулю.

Счётчик принадлежит клиенту, и доставка его не сообщает. Процесс, остановленный во время ожидания retry_after, теряет ожидание, а не сообщение: оно по-прежнему не подтверждено, и брокер доставит его снова после тайм-аута подтверждения или когда соединение консьюмера пропадёт.