Какие гарантии доставки сообщений предоставляет Google Pub/Sub?
Что проверяют
Знаете ли вы реальные настройки Pub/Sub, а не общие слова про очереди: что по умолчанию будут дубли, как включается exactly-once и чего он не покрывает. Следом спрашивают, как вы обрабатываете повторные доставки в Go-консьюмере.
Как отвечать
Базовая гарантия Pub/Sub это at-least-once. Сообщение придёт повторно, если подписчик не подтвердил его до истечения ack deadline (по умолчанию 10 секунд, настраивается до 600) или вызвал Nack. Изредка дубли бывают и без сбоев, поэтому обработчик должен быть идемпотентным.
Что стоит назвать дальше:
- exactly-once delivery: свойство подписки, включается флагом при её настройке. Работает только для pull-подписок и в пределах одного региона. Гарантирует, что после успешного ack сообщение не придёт снова. В Go-клиенте для этого вызывают
msg.AckWithResult()и проверяют результат: ack может не пройти, например из-за истёкшего дедлайна; - дубли на публикации: exactly-once не спасает, если продюсер из-за ретрая опубликовал одно и то же дважды. Это разные сообщения с разными ID, так что дедупликация по бизнес-ключу всё равно нужна;
- порядок: по умолчанию не гарантирован. Нужны ordering key у сообщений,
EnableMessageOrderingу публикующего клиента и включённый порядок на подписке. Соблюдается он только для одного ключа в одном регионе; - продление дедлайна:
Receiveв Go-клиенте сам продлевает аренду сообщения, пока колбэк работает, предел задаётсяMaxExtensionвReceiveSettings; - неудачные сообщения: retry policy с экспоненциальной задержкой и dead-letter topic с лимитом попыток от 5 до 100;
- хранение: неподтверждённые сообщения подписка по умолчанию держит 7 дней.
Где спотыкаются
Утверждают, что exactly-once в Pub/Sub избавляет от идемпотентности. Он не работает для push-подписок, не спасает от дублей на публикации и требует проверять результат ack.
Вызывают msg.Ack() сразу при получении, до обработки. Если процесс упадёт, сообщение потеряно, и это уже at-most-once.
Запускают долгую обработку, не настроив MaxOutstandingMessages и параллелизм: сообщения копятся в памяти, не успевают обработаться до дедлайна и приходят повторно.