Молодогвардейцев 454015 Россия, Челябинская область, город Челябинск 89085842764
MindHalls logo

RabbitMQ — установка и простейший пример на PHP

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