2. Что такое RabbitMQ
● RabbitMQ — это брокер сообщений, он берет на себя работу по приему,
маршрутизации и выдаче сообщений (а также HA, WebUI etc.)
● Сообщение состоит из тела и заголовков (plain text)
● Маршрутизация строится на связи exchanges и очередей
● Не единственный в своем роде: см. Kafka, ActiveMQ
● RabbitMQ реализует открытый протокол AMQP c расширениями
2
3. ● Дистрибутивы: https://www.rabbitmq.com/download.html
○ Ubuntu/Debian: есть .deb из официального PPA
○ Docker: https://hub.docker.com/_/rabbitmq/
○ Puppet: https://github.com/puppetlabs/puppetlabs-rabbitmq
● Web: http://localhost:15672, логин:пароль — admin:admin
● CLI:
# rabbitmq-plugins enable rabbitmq_management
# wget "http://localhost:15672/cli/rabbitmqadmin"
Как начать работать с RabbitMQ
3
4. Применение и особенности MQ
● Асинхронное/отложенное выполнение задач
● Распределение задач между потребителями
● Очереди с приоритетами (https://www.rabbitmq.com/priority.html)
● Pub/Sub
● RPC (Remote Procedure Calls)
● Шина сообщений для микросервисов
4
5. Exchanges & queues & routing keys
● Вы задаете exchange и routing_key сообщению при отправке
○ default exchange: все очереди связаны с ним по routing_key == queue_name
○ default exchange называется amq.direct или ""
○ 4 типа exchanges: direct, fanout (broadcast), topic (key pattern match), headers
(message headers match)
● Сообщения читаются из очередей (queue)
● Очередь накапливает сообщения, exchange — нет
5
6. Немного про маршрутизацию
● Упрощенная схема
● Не указан exchange
● Подразумевается default
exchange
● queue_name == routing_key
● Явно указан exchange
● Сообщения отправляются в X
● X связан с очередью
P X
C1
C2
6
7. Bindings
Binding (связь) — это описание, как сообщение попадает из exchange в queue
● Для default и fanout exchanges соответствие предустановлено
● Для остальных типов (direct, topic) соответствие задается через API,
management plugin или в WebUI
● Если exchange связан с несколькими очередями, каждая получает копию
сообщения
● Exchange без связей с очередями — это “/dev/null”
● Связи можно строить “на лету”, маршрутизацию можно зацикливать,
устанавливать TTL etc. 7
8. Channels
● Channel (канал) — это виртуальное легковесное соединение вашего
приложения с сервером RabbitMQ внутри одного TCP соединения
(connection)
● Каналы независимы друг от друга и не делят состояние друг друга
○ Delivery tags сообщений имеют нумерацию внутри канала (а не глобальную)
● Обычно вам нужен только один канал на приложение
○ Но на каждый thread создавайте отдельный channel (или используйте
блокировки)
● Закрытие канала приводит к отменам “висящих” подтверждений и 8
9. Delivery acks & nacks
● Сбой при обработке сообщения приведет к его потере. Для избежания
этого используется механизм подтверждений (acknowledgments)
получения
● Сообщения без подтверждения снова окажутся в очереди и могут быть
получены после восстановления от сбоя (или другими потребителями)
● Команда ack — сообщение обработано, удалить
● Команда nack — сообщение не обработано, удалить (см. DLX)
● ack/nack выполняется над delivery tag сообщения (узнаем при
получении) 9
10. Некоторые паттерны
Autodelete: no и Durable: yes для очередей
JSON-encoded тело сообщений
Прорабатываем ситуации:
● “ack on delivery” или подтверждаем вручную?
● ошибка при обработке сообщения: не падаем
● не можем обработать сообщение: reject, requeue или в другую очередь?
● потеряли сообщения (при обработке): как перезапустить все с начала
● такое сообщение уже получали: избегаем дублирования
10
11. Пример: обработка файлов
Было: приложение А пишет имена файлов в
таблицу БД, приложение Б периодически
считывает строки из таблицы и обрабатывает
файлы, после отмечает строки как
обработанные.
Плюсы: все имена файлов сохраняются
Минусы:
— требуется механизм блокировки записей
— блокировки усложняются при необходимости
добавить еще одного потребителя
— среднее время ожидания файла — 1/2
периода
Стало: приложение А отправляет сообщение,
приложение Б получает сообщение, производит
обработку, подтверждает получение.
Плюсы:
— не требуются блокировки
— легко добавить новых потребителей
— минимальное время ожидания файла
Минусы:
— обработанные сообщения не сохраняются
11
12. Dead Letter Exchange (DLX)
● Обычно мы хотим сохранить сообщения, которые мы не смогли
обработать для исследований. Например, отправив их в отдельную
очередь с ошибочными сообщениями
● Процесс можно упростить, настроив DLX для очереди. Nack сообщения
вместо удаления отправит его в указанный DLX (а далее по роутингу)
P X
C2
my_dlx
err_queue
my_queue
DLX=my_dlx
consume
12
13. Дальнейшее чтение
● Уроки и примеры RabbitMQ: https://www.rabbitmq.com/getstarted.html
● “Очереди и блокировки. Теория и практика” (HighLoad Junior):
https://habrahabr.ru/company/oleg-bunin/blog/316458/
● Надежность доставки и отказоустойчивость в RabbitMQ:
https://www.rabbitmq.com/reliability.html
13