Добрый день, Хабр! Хочу поделиться учебником-справочником знаний, которые мне удалось собрать по RabbitMQ
и сжать в короткие рекомендации и выводы.
Оглавление
- RabbitMQ. Часть 1. Introduction. Erlang, AMQP и RPC
- RabbitMQ. Часть 2. Разбираемся с Exchanges
- RabbitMQ. Часть 3. Разбираемся с Queues и Bindings
- RabbitMQ. Часть 4. Разбираемся с тем, что-такое сообщения и фреймы
- RabbitMQ. Часть 5. Производительность публикации и потребления сообщений
- RabbitMQ. Часть 6. Обзор модулей Federation и Shovel
- RabbitMQ. Часть 7. Подробно про Connection и Chanel
- RabbitMQ. Часть 8. RabbitMQ в .NET
- RabbitMQ. Часть 9. Мониторинг
Кратко про AMQP
AMQP (Advanced Message Queuing Protocol) — открытый протокол для передачи сообщений между компонентами системы. Основная идея состоит в том, что отдельные подсистемы (или независимые приложения) могут обмениваться произвольным образом сообщениями через AMQP-брокер, который осуществляет маршрутизацию, возможно гарантирует доставку, распределение потоков данных, подписку на нужные типы сообщений.
Протокол AMQP
вводит три понятия:
exchange
(обменник или точка обмена) — в неё отправляются сообщения. Обменник распределяет сообщение в одну или несколько очередей. Он маршрутизирует сообщения в очередь на основе созданных связей (binding
) между ним и очередьюqueue
(очередь) — структура данных на диске или в оперативной памяти, которая хранит ссылки на сообщения и отдает копии сообщенийconsumers
(потребителям). Одна очередь может использоваться несколькими потребителямиbinding
(привязка) — правило, которое сообщает точке обмена в какую из очередей эти сообщения должны попадать. Обменник и очередь могут быть связаны несколькими привязками
Протокол работает поверх TCP/IP.
Кратко про Erlang
Исходный код проекта находится в репозитории на GitHub. Архитектура RabbitMQ-server основана на Erlang и BEAM.
Erlang
разработан компаниейEricsson
в середине 1980-x как распределенная, отказоустойчивая, система реального времени для приложений, требующих безотказной работы 99,999%.Erlang
применяется в различных отраслях и современных приложениям, например в
Кратко про RabbitMQ
RabbitMQ – это брокер сообщений с открытым исходным кодом. Он маршрутизирует собщения по всем базовым принципам протокола AMQP описанным в спецификации. RabbitMQ
реализует и дополняет протокол AMQP
.
Основная идея модели обмена сообщениями в RabbitMQ
заключается в том, что producer
(издатель) не отправляет сообщения непосредственно в очередь. На самом деле и довольно часто издатель даже не знает, будет ли сообщение вообще доставлено в какую-либо очередь.
Вместо этого издатель может отправлять сообщения только на обмен. С одной стороны, обмен получает сообщения от издателей, а с другой — отправляет их в очереди. Обмен должен точно знать, что делать с полученным сообщением. Должно ли оно быть добавлено в определенную очередь? Должно ли оно быть добавлено в несколько очередей? Или сообщение нужно игнорировать.
Кратко работу RabbitMQ
можно описать следующим образом:
- Издатель отправляет сообщение определенному обменнику
- Обменник, получив сообщение, маршрутизирует его в одну или несколько очередей в соответствии с правилами привязки между ним и очередью
- Очередь хранит ссылку на это сообщение. Само сообщение хранится в оперативной памяти или на диске
- Как только потребитель готов получить сообщение из очереди, сервер создает копию сообщения по ссылке и отправляет
- Потребитель получает сообщение и отправляет брокеру подтверждение
- Брокер, получив подтверждение, удаляет копию сообщения из очереди. Затем удаляет из оперативной памяти и с диска
RPC
Процесс RPC (remote procedure call) лежит в основе практически всех взаимодействий с ядром RabbitMQ
. Например, начальные обсуждения условий клиента с RabbitMQ
, демонстрирует определённый процесс RPC
. Как только эта последовательность завершится, RabbitMQ
будет готов принимать запросы от клиента:
Также в спецификации AMQP
и клиент и сервер могут вызывать команды. Это означает, что клиент ожидает взаимодействие с сервером. Команды — это классы и методы. Например, Connection.Start
– вызов метода Start
класса Connection
.
Подключение и каналы
Для такого обмена информацией между клиентом и сервером используются каналы. Каналы создаются в рамках определенного подключения. Каждый канал изолирован от других каналов. В синхронном случае не возможно выполнять следующую команду, пока не получен ответ.
Для того чтобы иметь возможность отправлять команды параллельно приходится открывать несколько каналов. Каждый канал создает отдельный Erlang
процесс. Одно подключение может иметь множество каналов (multiplexing). Для каждого канала существуют некие структуры и объекты в памяти. Поэтому чем больше каналов имеется в рамках соединения, тем больше памяти использует RabbitMQ для управления таким соединением.
Простой пример создания подключения и канала при помощи RabbitMQ.Client:
// ...
private void TryConnect()
{
var factory = new ConnectionFactory()
{
HostName = "host_name",
UserName = "user_name",
Password = "p@ssword",
// Включение автоматического восстановления
// соединения после сбоев сети
AutomaticRecoveryEnabled = true
};
_connection = factory.CreateConnection();
}
// ...
public void CreateChannel()
{
_channel = _connection.CreateModel();
// other options
}
Открывать новое соединение для каждой операции, настоятельно не рекомендуется, поскольку это приведет к большим затратам. Каналы также должны быть постоянными, но многие ошибки протокола приводят к закрытию канала, поэтому срок службы канала может быть короче, чем у соединения.
Где используется RabbitMQ?
В контексте микросервисов протокол AMQP
и его реализацию в RabbitMQ
часто используют для асинхронного взаимодействия между сервисами.
В контексте IIOT
протокол AMQP
и его реализацию в RabbitMQ
используют для обмена данными между серверами (сервер-сервер). Также используют плагин MQTT Plugin RabbitMQ являющегося реализацией протокола MQTT для передачи данных между датчиком и сервером в низкоскоростных средах с высокой задержкой (полный перечень поддерживаемых протоколов перечислен на сайте проекта).
В следующей статье начнем разбираться подробнее с Exchanges.
Shaz
Я конечно понимаю, что не сложно разобраться о чем тут речь. Но какого черта?