AMQP logo Сегодня довольно мало информации о протоколе [AMQP](http://www.amqp.org/) (Advanced Message Queueing Protocol) и его применении, особенно русском языке. А вообще это - замечательный, уже достаточно широко поддерживаемый открытый протокол для передачи сообщений между компонентами системы с низкой задержкой и на высокой скорости. При этом семантика обмена сообщениями настраивается под нужды конкретного проекта. Такие решения существовали и ранее, но это первый стандарт, для которого существует большое количество свободных реализаций. Основная идея состоит в том, что отдельные подсистемы (или независимые приложения) могут обмениваться произвольным образом сообщениями через AMQP-брокер, который осуществляет маршрутизацию, возможно гарантирует доставку, распределение потоков данных, подписку на нужные типы сообщений. В качестве классических примеров обычно приводятся финансовые приложения, связанные, например, с доставкой потребителям информации о курсах ценных бумаг в режиме реального времени, также возможно RPC-взаимодействие двух подсистем, которые не имеют связи друг с другом (взаимодействие через общий протокол AMQP) и так далее и тому подобное. Сегодня тема доставки информации в реальном времени является крайне актуальной (достаточно вспомнить хотя бы Twitter, Google Wave). И здесь системы передачи сообщений могут служить внутренним механизмом обмена данными, который обеспечивает доставку данных (изменений данных) клиентам. Я не ставлю своей целью сегодня рассказать о том, как писать приложения для AMQP. Хочу лишь немного рассказать о том, что это совсем не страшно, не очень сложно, и действительно работает, хотя стандарт находится еще в развитии, выходят новые версии протокола, брокеров и т.п. Но это уже вполне production-quality. Расскажу лишь базовые советы, чтобы помочь "въехать" в протокол. Для начала, маленькая коллекция ссылок (в основном, на английском): что такое вообще обмен сообщениями и почему AMQP такой ([Messaging in general and AMQP design](http://www.zeromq.org/whitepapers:amqp-analysis)); сравнение различных реализаций обмена сообщениями, в частности основанных на AMQP ([Message Queue Comparison](http://wiki.secondlife.com/wiki/Message_Queue_Evaluation_Notes)); клиентская библиотека AMQP для Twisted Framework (Python) с поддержкой Thrift ([Thrift, AMQP in Twisted](http://us.pycon.org/2009/conference/schedule/event/28/)); руководство от Red Hat о том, что такое messaging и как работать с AMQP, описывает их "коробочный" продукт на основе AMQP, но подходит и для любых AMQP-брокеров ([AMQP Programming Tutorial for C++, Java, and Python](http://www.redhatpress.org/docs/en-US/Red_Hat_Enterprise_MRG/1.0/pdf/Messaging_Tutorial/Messaging_Tutorial.pdf)); достаточно много документации, описаний архитектурных решений на сайте [ZeroMQ](http://www.zeromq.org/), который не совсем AMQP-брокер, но общая архитектура, детали реализации представляют отдельный интерес; обзорная статья от Duncan McGregor о txAMQP и AMQP в общем ([A Simfonia on Messaging with txAMQP](http://feedproxy.google.com/~r/ElectricDuncan/~3/NKiCEOnzXe0/sinfonia-on-messaging-with-txamqp.html), II, III) Далее необходимо выбрать AMQP-брокер, который вы будете использовать. При выборе необходимо рассматривать как собственно характеристики сервера: скорость работы, надежность, легкость установки и поддержки, но также внимательно смотреть на версию AMQP-протокола, которая поддерживается брокером, - она должна совпадать с версией клиентской AMQP-библиотеки. Из брокеров я бы посоветовал [RabbitMQ](http://www.rabbitmq.com/), написанный на Erlang, и [Qpid](http://qpid.apache.org/), версии на C++ (AMQP 0-10) и Java (0-8, 0-9). Сам протокол AMQP устроен достаточно интересно: на самом нижнем уровне определяется формат кодирования данных в бинарный вид для передачи по TCP-соединению, выше лежит формат передачи RPC-запросов между сервером и клиентом. Сама семантика работы с сообщениями, создания очередей и т.п. описывается в XML-спецификации, которая по сути задает RPC-интерфейс сервера и клиента (примеры таких XML-файлов для версий [0-8](http://jira.amqp.org/confluence/download/attachments/720900/amqp0-8.xml?version=1) и [0-10](http://jira.amqp.org/confluence/download/attachments/720900/amqp.0-10.xml?version=1)). Этот XML является последней и конечной спецификацией протокола. Более того, версии протокола 0-8 и 0-10 отличаются настолько сильно, что поддерживать их одновременно вряд ли возможно в одной программе. Что еще более интересно, иногда такие spec-файлы для разных брокеров AMQP, формально поддерживающих одну и ту же версию протокола, отличаются настолько, что не являются взаимозаменяемыми. Но это скорее небольшие технические проблемы. AMQP основан на трех понятиях: 1. Сообщение (message) - единица передаваемых данных, основная его часть (содержание) никак не интерпретируется сервером, к сообщению могут быть прицеплены структурированные заголовки. 1. Точка обмена (exchange) - в нее отправляются сообщения. Точка обмена распределяет сообщения в одну или несколько очередей. При этом в точке обмена сообщения не хранятся. Точки обмена бывают трех типов: fanout - сообщение передается во все прицепленные к ней очереди; direct - сообщение передается в очередь с именем, совпадающим с ключом маршрутизации (routing key) (ключ маршрутизации указывается при отправке сообщения); topic - нечто среднее между fanout и exchange, сообщение передается в очереди, для которых совпадает маска на ключ маршрутизации, например, ``app.notification.sms.*`` - в очередь будут доставлены все сообщения, отправленные с ключами, начинающимися на ``app.notification.sms``. 1. Очередь (queue) - здесь хранятся сообщения до тех пор, пока не будет забраны клиентом. Клиент всегда забирает сообщения из одной или нескольких очередей. Меня в AMQP привлек эффективный бинарный протокол, ориентированность протокола на минимальные задержки и гибкость настройки. Я его использовал для рассылки сообщений всем серверам кластера (fanout exchange) и организации аналогов "почтовых ящиков", в которые доставляются сообщения, адресованные определенным клиентам (direct exchange). Для получения сообщений нет необходимости опрашивать сервер, достаточно подписаться на сообщения из очереди, и сервер передаст их в тот момент, когда они появятся. В качестве клиентской библиотеки я выбрал библиотеку txAMQP для Twisted Framework (Python). В общем и целом все работает, но где-то требуются небольшие "доделки" и "подкрутки", которые я планирую опубликовать на launchpad. В AMQP и вокруг AMQP есть много интересного и перспективного. К примеру, брокер RabbitMQ умеет масштабироваться и работать в едином кластере. Мне кажется, это очень полезная и перспективная технология.