RabbitMQ — это мощный инструмент, реализующий обмен сообщениями между компонентами программной среды, будь-то процессы, web-приложения, клиент-сервер и прочее. Обмен сообщениями происходит по стандарту AMQP, который своим появлением решил огромную кучу проблем и вылечил множество головных болей разработчиков.
Самым большим преимуществом является то, что стандарт доступен в огромном количестве языков программирования, это позволяет обмениваться сообщениями скрипту на PHP со скриптом на Python и им обоим отправлять сообщения на сервер, который написан на Java. В двух словах — очень удобно!
Основные термины:
Producer — поставщик — программа, которая отправляет сообщения в очередь.
Consumer — подписчик — программа, которая принимает сообщения из очереди, чаще всего находится в режиме ожидания и при получении сообщения сразу же приступает к его обработке.
Queue — очередь — та самая «труба» через которую сообщения от поставщика попадают к подписчику. Очередь не имеет ограничений ни на количество поставщиков, ни на количество подписчиков и даже нет ограничения на количество сообщений, хранящихся в ней на данный момент. Существует очередь внутри самого RabbitMQ и им же полностью обслуживается, наша забота только в том, чтобы отправлять в нее сообщения и получать их.
Про глубинный принцип работы инструмента сейчас писать не буду, возможно в одном из следующих включений, лучше расскажу как установить, настроить и начать пользоваться Rabbitом.
Установка RabbitMQ на Linux
Первый делом нужно установить RabbitMQ Server, который как раз отвечает за "трубу", через которую будут посылаться сообщения, его наличие в системе гарантирует успех.
В системах, основанных на Debian, в том числе и Ubuntu, установить сервер можно через терминал из стандартного репозитория, но в этом случае не гарантируется свежая версия программы.
apt-get install rabbitmq-server
Самую свежую версию можно скачать на официальном сайте по этой ссылочке. Загружаем .deb пакет и устанавливаем его следующим образом.
dpkg -i rabbitmq-server_3.6.9-1_all.deb
После этого можно подключать библиотеку Rabbitа уже непосредственно в проект.
Подключить RabbitMQ в проект с помощью Composer
У меня уже были заметки про установку библиотек с помощью Composer`а, это очень удобно. Создаем в папке с проектом файл composer.json и пишем туда такое содержимое.
{
"require" : {
"php-amqplib/php-amqplib" : ">=2.6.1"
}
}
Далее открываем папку с проектом и терминале и запускаем установку зависимостей
composer install
После этого в корне проекта появится папка vendor с установленной в ней библиотекой RabbitMQ.
Возможные проблемы! Иногда композер не может найти некоторые библиотеки в системе, например, у меня не нашлось двух библиотек, их нужно просто доустановить. В моем случае это были php-bcmath и php-mbstring, установить их легко.
apt-get install php-bcmath apt-get install php-mbstring
Следующим шагом будет подключить файл autoloader.php в файлы исходного кода в своем проекте с помощью require_once, например, если файл script.php лежит в корне проекта, то строчка будет выглядеть вот так
require_once __DIR__ . '/vendor/autoload.php';
С этого момента можно пользоваться библиотечными функциями.
Пример обмена сообщением с помощью RabbitMQ
В заголовке статьи обозначено, что пример подключения в проект и использования библиотеки я приведу на PHP. А пример будет простейший — два скрипта, одна очередь. Скрипт producer.php отправит в очередь сообщение со строкой, а скрипт consumer.php будет «слушать» очередь и выводить все строки, которые оттуда получит.
producer.php
<?php
//Файл с исходным кодом лежит в /application/hello-world, поэтому нужно спуститься на два уровня
//прежде, чем подключить vendor
require_once __DIR__ . '/../../vendor/autoload.php';
//Необходимые классы
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
//Создаем соединение
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
//Берем канал и декларируем в нем новую очередь, первый аргумент - название
$channel = $connection->channel();
$channel->queue_declare('hello', false, false, false, false);
//Создаем новое сообщение
$msg = new AMQPMessage('Hello World!');
//Отправляем его в очередь
$channel->basic_publish($msg, '', 'hello');
echo " [x] Sent 'Hello World!'\n";
//Не забываем закрыть канал и соединение
$channel->close();
$connection->close();
?>
consumer.php
<?php
//Файл с исходным кодом лежит в /application/hello-world, поэтому нужно спуститься на два уровня
//прежде, чем подключить vendor
require_once __DIR__ . '/../../vendor/autoload.php';
//Подключаем нужный класс
use PhpAmqpLib\Connection\AMQPStreamConnection;
//Создаем соединение
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
//Берем канал и декларируем в нем очередь, важно чтобы названия очередей совпадали
$channel = $connection->channel();
$channel->queue_declare('hello', false, false, false, false);
echo ' [*] Waiting for messages. To exit press CTRL+C', "\n";
//Функция, которая будет обрабатывать данные, полученные из очереди
$callback = function($msg) {
echo " [x] Received ", $msg->body, "\n";
};
//Уходим слушать сообщения из очереди в бесконечный цикл
$channel->basic_consume('hello', '', false, true, false, false, $callback);
while(count($channel->callbacks)) {
$channel->wait();
}
//Не забываем закрыть соединение и канал
$channel->close();
$connection->close();
?>
Заключение
На самом деле инструмент очень мощный, позволяет строить очень гибкие архитектурные решения и не заморачиваться над передачей сообщений между компонентами. Вполне возможно, что я напишу еще несколько заметок о RabbitMQ с примерами посложнее или о том, как он работает. Ну а пока у меня все, спасибо за внимание!