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 с примерами посложнее или о том, как он работает. Ну а пока у меня все, спасибо за внимание!