Обмен сообщениями по протоколу AMQP между PHP и Python c помощью сервера RabbitMQ

 

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

Установка сервера из официального репозитория нам не подойдет. У нас есть два пути это собрать rabbitmq-server из исходников, либо просто скачать deb пакеты с официального сайта проекта и установить их. Я предпочел второй путь.


Для начало установим erlang-nox:

#aptitude install erlang-nox

Теперь скачиваем deb пакеты с официального сайта проекта RabbitMQ и устанавливаем их в систему:

#wget http://www.rabbitmq.com/releases/rabbitmq-server/v2.4.1/rabbitmq-server_2.4.1-1_all.deb
#dpkg -i rabbitmq-server_2.4.1-1_all.deb

Сейчас создадим необходимые конфигурационные файлы. Запускаем редактор

#nano /etc/rabbitmq/rabbitmq.config

и вносим в него следующие параметры (документацию можете посмотреть на официальном сайте):

[
  {mnesia, [{dump_log_write_threshold, 1000}]},
  {rabbit, []}
].

Аналогично создаётся конфигурационный файл окружения. Открываем редактор

#nano /etc/rabbitmq/rabbitmq-env.conf

и добавляем в файл следующие строки:

NODENAME=rabbit@localhost
NODE_IP_ADDRESS=127.0.0.1

Для удобства работы устанавливаем различные плагины. Для установки достаточно просто поместить их в необходимый каталог:

#cd /usr/lib/rabbitmq/lib/rabbitmq_server-2.4.1/plugins/
#wget http://cd /usr/lib/rabbitmq/lib/rabbitmq_server-2.4.1/plugins/
#wget http://www.rabbitmq.com/releases/plugins/v2.4.1/mochiweb-2.4.1.ez
#wget http://www.rabbitmq.com/releases/plugins/v2.4.1/webmachine-2.4.1.ez
#wget http://www.rabbitmq.com/releases/plugins/v2.4.1/amqp_client-2.4.1.ez
#wget http://www.rabbitmq.com/releases/plugins/v2.4.1/rabbitmq-mochiweb-2.4.1.ez
#wget http://www.rabbitmq.com/releases/plugins/v2.4.1/rabbitmq-management-agent-2.4.1.ez
#wget http://www.rabbitmq.com/releases/plugins/v2.4.1/rabbitmq-management-2.4.1.ez

Перезагрузим сервер:

#service rabbitmq-server restart

Проверим лог загрузки и состояние сервера:

$tail -100 /var/log/rabbitmq/startup_log
$/usr/sbin/rabbitmqctl list_queues

Устанавливаем библиотеку для работы PHP с AMQP

Для работы с сервером для PHP необходимо собрать библиотеку amqp.
Скачиваем исходные коды библиотеки C для работы с AMQP:

hg clone http://hg.rabbitmq.com/rabbitmq-c/rev/3c549bb09c16 rabbitmq-c
cd rabbitmq-c
hg clone http://hg.rabbitmq.com/rabbitmq-codegen/rev/f8b34141e6cb codegen

Установим его в операционную систему:

autoreconf -i && ./configure && make && sudo make install

Сборку модуля для PHP произведем с помощью PECL:

pecl install amqp

Пара скриптов для тестирования

Теперь составим парочку простых скриптов. PHP-скрипт будет передавать сообщение в точку обмена, а скрипт на python подхватит его и покажет.

#nano test.php
<?php
// Создаем новое соединение
$cnn1 = new AMQPConnection();
$cnn1->setHost('localhost');
$cnn1->setLogin('guest');
$cnn1->setPassword('guest');
$cnn1->setVhost('/');
$cnn1->connect();
 
// Объявляем точку обмена
$ex1 = new AMQPExchange($cnn1);
$phpid = uniqid('php_');
$ex1->declare('test',AMQP_EX_TYPE_DIRECT,AMQP_DURABLE);
 
// Собственно наше сообщение потомкам :)
$mess = << 'text/plain',
'Content-encoding'=>'UTF-8',
'message_id' => $phpid,
);
 
//Публикуем наше сообщение
$ex1->publish($mess,'test.messages',0,$atrib);
$cnn1->disconnect();
 
?>

Займемся скриптом на python:

#aptitude install python-virtualenv
#cd /opt
#virtualenv  no-site-packages myapp
#cd myapp/
#. ./bin/activate

и быстренько составим скрипт:

#mkdir testamqp
#cd testamqp
#nano wait.py

 

#!/bin/env python
# Подключаем библиотеку для работы с протоколом amqp
import amqplib.client_0_8 as amqp
# This is the function that basic_consume will send messages to                              
def process_message( message ):
 """ Callback function used by channel.basic_consume """
 print 'Received: %s' % message.body
 
# Указываем хост и порт с сервером RabbitMQ
host = '127.0.0.1'
port = 5672
 
# Информация о точке обмена и очереди
exchange_name = 'test'
exchange_type = 'direct'
queue_name = 'messages'
routing_key = 'test.messages'
 
# Установим переменную в TRUE дальше мы ее будем использовать
process_messages = True
 
# Устанавливаем соединение с сервером
connection= amqp.Connection( host ='%s:%s' % ( host, port ),
 userid = 'guest',
 password = 'guest',
 ssl = False,
 virtual_host = '/' )
 
# Создаем канал
channel = connection.channel()
 
# Декларируем нашу точку обмена
channel.exchange_declare( exchange = exchange_name,
 type = exchange_type,
 durable = True,
 auto_delete = False )
 
# Создаем очередь
channel.queue_declare( queue = queue_name ,
 durable = True,
 exclusive = False,
 auto_delete = True )
 
# Подпиываемся на очередь и точку обмена
channel.queue_bind( queue = queue_name,
 exchange = exchange_name,
 routing_key = routing_key )
 
# Let AMQP know to send us messages
consumer_tag = channel.basic_consume( queue = queue_name,
 no_ack = True,
 callback = process_message )
print consumer_tag
# Создаем петлю process_messages = True
while process_messages:
 
 # Ждем сообщений
 channel.wait()            
 
# Закрываем канал
channel.close()
 
# Закрываем наше соединение
connection.close()
 
# This might go somewhere like a signal handler
def cancel_processing():
 """ Stop consuming messages from RabbitMQ """
 global channel, consumer_tag, process_messages
 
 # Do this so we exit our main loop
 process_message = False          
 
 # Tell the channel you dont want to consume anymore 
 channel.basic_cancel( consumer_tag )

Запускаем скрипт, который будет ожидать сообщения:

python wait.py

Из другой консоли запускаем скрипт на php:

php test.php

Чудо: в первой консоли мы получили сообщение, отправленое из второй, и сейчас оно гордо светится в консоли!!!

Поправде говоря, я сильно покромсал код, использующийся у меня 🙂 , но вроде проверил: все в рабочем состоянии. Главное, что мне хотелось показать, это возможность так красиво наладить обмен сообщениями между PHP и Python.

P.S. забыл добавить, что при установки плагинов к rabbitmq-server вы получили красивый веб-интерфейс.

Обмен сообщениями по протоколу AMQP между PHP и Python c помощью сервера RabbitMQ: 2 комментария

Добавить комментарий