Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.
Подтверждения и транзакции
Публикация в RabbitMQ завершается, когда кадр записан, когда сервер её подтвердил или когда фиксируется транзакция канала.
Схема текстом
- Без ожидания: basic.publish; Возвращается, когда кадр записан
- Подтверждения: confirm.select один раз; basic.publish; basic.ack или basic.nack на каждое сообщение; Сообщение, не попавшее ни в одну очередь, подтверждается и отбрасывается: крейт публикует без флага mandatory
- Транзакция: tx.select один раз; basic.publish одна или больше; tx.commit; commit-ok: все публикации видны
- basic.publish → Возвращается, когда кадр записан
- confirm.select один раз → basic.publish
- basic.publish → basic.ack или basic.nack на каждое сообщение
- tx.select один раз → basic.publish одна или больше
- basic.publish одна или больше → tx.commit
- 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 (подтверждения издателя, транзакции).