Добрый день, Хабр! Хочу поделиться учебником-справочником знаний, которые мне удалось собрать по 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 вводит три понятия:


rabbitmq_1


  • exchange (обменник или точка обмена) — в неё отправляются сообщения. Обменник распределяет сообщение в одну или несколько очередей. Он маршрутизирует сообщения в очередь на основе созданных связей (binding) между ним и очередью
  • queue (очередь) — структура данных на диске или в оперативной памяти, которая хранит ссылки на сообщения и отдает копии сообщений consumers (потребителям). Одна очередь может использоваться несколькими потребителями
  • binding (привязка) — правило, которое сообщает точке обмена в какую из очередей эти сообщения должны попадать. Обменник и очередь могут быть связаны несколькими привязками

Протокол работает поверх TCP/IP.


Кратко про Erlang


Исходный код проекта находится в репозитории на GitHub. Архитектура RabbitMQ-server основана на Erlang и BEAM.


Erlang разработан компанией Ericsson в середине 1980-x как распределенная, отказоустойчивая, система реального времени для приложений, требующих безотказной работы 99,999%. Erlang применяется в различных отраслях и современных приложениям, например в WhatsApp. Подробнее можно прочитать в статье архитектура WhatsApp, которую Facebook купил за $19 миллиардов

Кратко про RabbitMQ


RabbitMQ – это брокер сообщений с открытым исходным кодом. Он маршрутизирует собщения по всем базовым принципам протокола AMQP описанным в спецификации. RabbitMQ реализует и дополняет протокол AMQP.


Основная идея модели обмена сообщениями в RabbitMQ заключается в том, что producer (издатель) не отправляет сообщения непосредственно в очередь. На самом деле и довольно часто издатель даже не знает, будет ли сообщение вообще доставлено в какую-либо очередь.


Вместо этого издатель может отправлять сообщения только на обмен. С одной стороны, обмен получает сообщения от издателей, а с другой — отправляет их в очереди. Обмен должен точно знать, что делать с полученным сообщением. Должно ли оно быть добавлено в определенную очередь? Должно ли оно быть добавлено в несколько очередей? Или сообщение нужно игнорировать.


Image from: http://bit.ly/2U3PyJz


Кратко работу RabbitMQ можно описать следующим образом:


  1. Издатель отправляет сообщение определенному обменнику
  2. Обменник, получив сообщение, маршрутизирует его в одну или несколько очередей в соответствии с правилами привязки между ним и очередью
  3. Очередь хранит ссылку на это сообщение. Само сообщение хранится в оперативной памяти или на диске
  4. Как только потребитель готов получить сообщение из очереди, сервер создает копию сообщения по ссылке и отправляет
  5. Потребитель получает сообщение и отправляет брокеру подтверждение
  6. Брокер, получив подтверждение, удаляет копию сообщения из очереди. Затем удаляет из оперативной памяти и с диска

RPC


Процесс RPC (remote procedure call) лежит в основе практически всех взаимодействий с ядром RabbitMQ. Например, начальные обсуждения условий клиента с RabbitMQ, демонстрирует определённый процесс RPC. Как только эта последовательность завершится, RabbitMQ будет готов принимать запросы от клиента:


rabbitmq_2


Также в спецификации AMQP и клиент и сервер могут вызывать команды. Это означает, что клиент ожидает взаимодействие с сервером. Команды — это классы и методы. Например, Connection.Start – вызов метода Start класса Connection.


Подключение и каналы


Для такого обмена информацией между клиентом и сервером используются каналы. Каналы создаются в рамках определенного подключения. Каждый канал изолирован от других каналов. В синхронном случае не возможно выполнять следующую команду, пока не получен ответ.


Для того чтобы иметь возможность отправлять команды параллельно приходится открывать несколько каналов. Каждый канал создает отдельный Erlang процесс. Одно подключение может иметь множество каналов (multiplexing). Для каждого канала существуют некие структуры и объекты в памяти. Поэтому чем больше каналов имеется в рамках соединения, тем больше памяти использует RabbitMQ для управления таким соединением.


rabbitmq_3


Простой пример создания подключения и канала при помощи 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.


Ссылки