RabbitMQ установка и использование (Debian, Web, Php)

Сегодня мне понадобилось связать два скриптика на php-cli между собой.

Раньше я делал на том, что всегда знаю, т.е. использовал RAM-таблицы mysql для обмена между несколькими скриптами, но там слишком большая нагрузка начиналась, когда запрос несколько раз в секунду в базу кидал для получения новых сообщений, да и последнее время решил не использовать то что давно знаю, а постоянно что-то новое осваивать, что и вам советую.

Один скрипт работает и просит периодами второй что-то там обработать и тот ему отвечает, этот получает информацию... Очень удобно...

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

Установка сервера RabbitMQ

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

Установка RabbitMQ на сервер под Debian 9 происходит вот так

apt-get install rabbitmq-server

Веб-интерфейс RabbitMQ

Если вы желаете потренироваться, помониторить и посмотреть наглядно что у вас происходит на сервере, в RabbitMQ есть плагин, который предоставляет веб-интерфейс, очень крутая фича.

Веб-интерфейс в RabbitMQ включается следующим образом:

rabbitmq-plugins enable rabbitmq_management

После этого, можете зайти на свой сервер по порту 15672

Создание пользователя в RabbitMQ

Но, чтобы работать дальше с RabbitMQ, нам нужно создать пользователя, пусть он будет называться userok а пароль у него будет pass123

Для добавления пользователя администратора, нам нужно ввести в консоли следующее

rabbitmqctl add_user userok pass123
rabbitmqctl set_user_tags userok administrator
rabbitmqctl set_permissions -p / userok ".*" ".*" ".*"

После этого можете заходить с этим логином и паролем в веб-интерфейс на порт 15672 тут можно и поиграться с очередями и посмотреть что получается в результате работы ваших приложений.

Работа с сообщениями

На этой странице вы найдете исчерпывающий список библиотек для реализации работы с RabbitMQ.

Нам же сегодня нужно придумать как применить это в проекте на php.

Cудя по описанию, pecl amqp library собрана на C-клиенте RabbitMQ

Исходники проекта и его описание с примерами использования вот тут на гитхабе.

Как я подумал, то что в репозитории Debian названо php-amqp - это оно и есть, попробуем его установить

apt-get install php-amqp

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

Сохраним этот файл с именем send.php

<?
//Establish connection to AMQP
$connection = new AMQPConnection();
$connection->setHost('127.0.0.1');
$connection->setLogin('userok');
$connection->setPassword('pass123');
$connection->connect();
//Create and declare channel
$channel = new AMQPChannel($connection);
//AMQPC Exchange is the publishing mechanism
$exchange = new AMQPExchange($channel);


//название цепочки
$routing_key = 'hello';


//это важно при отсутствии цепочки с именем hello
$queue = new AMQPQueue($channel);
$queue->setName($routing_key);
$queue->setFlags(AMQP_NOPARAM);
$queue->declareQueue();


//тут уже просто размещение сообщения
$message = 'test '.microtime();
$exchange->publish($message, $routing_key);

//а тут отключение
$connection->disconnect();

Тут нужно понимать, если мы по Long Pool будем данные собирать, то в цикле будет бесконечное получение обновлений c сервера  и раскидывание по цепочкам, клиент обновлений не будет тратить время на какой-то там анализ, он молниеносно раскидывает в цепочки и всё. Ну и логичным будет блок декларирования цепочки на всякий случай один раз в начале запускать, а дисконект где-то после цикла или его вообще тут не будет, т.к. скрипт сколько живет столько и будет общаться с RabbitMQ

Long Pool - это что за зверь? Об этом будет отдельная статья...

Дальше принимающий скрипт, примерно такой, создадим его с именем reseive.php

$connection = new AMQPConnection();
$connection->setHost('127.0.0.1');
$connection->setLogin('userok');
$connection->setPassword('pass123');
$connection->connect();
//Create and declare channel
$channel = new AMQPChannel($connection);
//AMQPC Exchange is the publishing mechanism
$exchange = new AMQPExchange($channel);
$callback_func = function(AMQPEnvelope $message, AMQPQueue $q) use (&$max_consume) {
	echo PHP_EOL, "------------", PHP_EOL;
	echo " [x] Received ", $message->getBody(), PHP_EOL;
	echo PHP_EOL, "------------", PHP_EOL;
	$q->nack($message->getDeliveryTag());
	sleep(1);
	
};
try{
	$routing_key = 'hello';
	
	$queue = new AMQPQueue($channel);
	$queue->setName($routing_key);
	$queue->setFlags(AMQP_NOPARAM);
	$queue->declareQueue();
	echo ' [*] Waiting for messages. To exit press CTRL+C ', PHP_EOL;
	$queue->consume($callback_func);
}catch(AMQPQueueException $ex){
	print_r($ex);
}catch(Exception $ex){
	print_r($ex);
}
echo 'Close connection...', PHP_EOL;
$queue->cancel();
$connection->disconnect();

Открываем два терминала, например по SSH на нашу виртуалку, на одном стартуем php reseive.php, он будет жить пока не нажмешь ctrl+c, теперь на втором будем запускать php send.php и смотреть на вывод первого, если всё работает, то сиесекундно при выполнении первого скрипта во втором будет сообщение, вот так работает доставка. Работает она быстро.

Это всего лишь вводный курс, если вы захотите разобраться с этой технологией, то вам придется много экспериментировать, лучше если это будет на реальном проекте, желательно не на том, который по-работе, лучше по фану что-то делать.

Вы можете почитать полную документацию на php.net, только она на данный момент кроме датского никакой язык не поддерживает, может быть руки дойдут, переведу, анализируя код, вот ссылка http://docs.php.net/manual/da/book.amqp.php

Показать комментарии