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

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

Подтверждения и транзакции

Публикация в RabbitMQ завершается, когда кадр записан, когда сервер её подтвердил или когда фиксируется транзакция канала.

Три способа завершить публикацию: без ожидания - когда кадр записан, с подтверждениями - когда ответил сервер, в транзакции - при фиксацииБез ожиданияПодтвержденияТранзакцияbasic.publishВозвращается,когда кадрзаписанconfirm.selectодин разbasic.publishbasic.ack илиbasic.nack накаждое сообщениеtx.selectодин разbasic.publishодна или большеtx.commitcommit-ok:все публикациивидныСообщение, не попавшее ни в одну очередь, подтверждаетсяи отбрасывается: крейт публикует без флага mandatory
Схема текстом
  1. Без ожидания: basic.publish; Возвращается, когда кадр записан
  2. Подтверждения: confirm.select один раз; basic.publish; basic.ack или basic.nack на каждое сообщение; Сообщение, не попавшее ни в одну очередь, подтверждается и отбрасывается: крейт публикует без флага mandatory
  3. Транзакция: tx.select один раз; basic.publish одна или больше; tx.commit; commit-ok: все публикации видны
  4. basic.publish → Возвращается, когда кадр записан
  5. confirm.select один раз → basic.publish
  6. basic.publish → basic.ack или basic.nack на каждое сообщение
  7. tx.select один раз → basic.publish одна или больше
  8. basic.publish одна или больше → tx.commit
  9. tx.commit → commit-ok: все публикации видны

У basic.publish нет собственного ответа. Издатель, который отправил кадр и пошёл дальше, ничего не узнаёт о сообщении: отсутствующий обменник или сбой очереди остаются незамеченными.

Подтверждения издателя добавляют этот ответ. После confirm.select канал нумерует свои публикации, а сервер отвечает на каждую командой basic.ack, когда берёт ответственность за сообщение. Для постоянного сообщения в устойчивой очереди это значит, что оно записано на диск; для кворумной очереди - что его приняло большинство реплик. basic.nack означает, что сервер не смог обработать сообщение. Это редкость: такой ответ возникает из-за внутренней ошибки очереди.

Сообщение, которому не подошла ни одна привязка, тоже подтверждается. Обменник не находит очереди, сервер подтверждает сообщение и отбрасывает его. Вернуть такое сообщение издателю сервер может только при флаге mandatory.

Транзакция канала накапливает публикации на сервере. После tx.select публикации ждут tx.commit; commit-ok означает, что все они видны, а tx.rollback их отменяет. Каждая фиксация - это обращение к серверу с ожиданием ответа. RabbitMQ не обещает атомарности, если узел отказывает во время фиксации.

В этом крейте​

Режим определяет политика публикации, а более строгий режим - это другая политика:

ПолитикаКаналПубликация возвращается
LapinPublishодин канал на все такие издатели соединениякогда кадр записан
ConfirmsPublishсобственный, в режиме подтвержденийкогда сервер подтвердил; отрицательное подтверждение - ошибка
ServerTxPublishсобственный, в режиме транзакцийвнутри транзакции, при фиксации

Канал подтверждений или транзакций открывается при первой публикации, поэтому политика, которая ни разу не публикует, не держит канала. Каждая публикация уходит без mandatory, поэтому подтверждённая публикация могла не попасть ни в одну очередь: подтверждение говорит, что сервер принял сообщение, а не что его хранит очередь. Сообщения постоянные, если политика не задаёт другого.

Ошибка канала закрывает канал, а соединение остаётся открытым. Для этого достаточно публикации без ожидания в несуществующий обменник, причём издатель не видит ответа сервера. Следующая публикация открывает новый канал. Исключение - канал транзакций, закрывшийся с открытой транзакцией: транзакция существовала в этом канале, поэтому фиксация возвращает ошибку, а не сообщает об успехе.

Транзакция ConfirmsPublish - это буфер в сервисе. Фиксация публикует накопленные сообщения по порядку и ждёт каждого подтверждения. Она надёжна для каждого сообщения, но не атомарна: сообщения, отправленные до неудачного, остаются опубликованными. Транзакция ServerTxPublish - собственная транзакция RabbitMQ. Она одна на канал, потому что tx.select переводит в режим транзакций сам канал.

Правила протокола задаёт RabbitMQ (подтверждения издателя, транзакции).