AMQP по-русски 7

Posted by Андрей on Июнь 08, 2009

AMQP logo Сегодня довольно мало информации о протоколе AMQP (Advanced Message Queueing Protocol) и его применении, особенно русском языке. А вообще это – замечательный, уже достаточно широко поддерживаемый открытый протокол для передачи сообщений между компонентами системы с низкой задержкой и на высокой скорости. При этом семантика обмена сообщениями настраивается под нужды конкретного проекта. Такие решения существовали и ранее, но это первый стандарт, для которого существует большое количество свободных реализаций.

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

Сегодня тема доставки информации в реальном времени является крайне актуальной (достаточно вспомнить хотя бы Twitter, Google Wave). И здесь системы передачи сообщений могут служить внутренним механизмом обмена данными, который обеспечивает доставку данных (изменений данных) клиентам.

Я не ставлю своей целью сегодня рассказать о том, как писать приложения для AMQP. Хочу лишь немного рассказать о том, что это совсем не страшно, не очень сложно, и действительно работает, хотя стандарт находится еще в развитии, выходят новые версии протокола, брокеров и т.п. Но это уже вполне production-quality. Расскажу лишь базовые советы, чтобы помочь «въехать» в протокол.

Для начала, маленькая коллекция ссылок (в основном, на английском): что такое вообще обмен сообщениями и почему AMQP такой (Messaging in general and AMQP design); сравнение различных реализаций обмена сообщениями, в частности основанных на AMQP (Message Queue Comparison); клиентская библиотека AMQP для Twisted Framework (Python) с поддержкой Thrift (Thrift, AMQP in Twisted); руководство от Red Hat о том, что такое messaging и как работать с AMQP, описывает их «коробочный» продукт на основе AMQP, но подходит и для любых AMQP-брокеров (AMQP Programming Tutorial for C++, Java, and Python); достаточно много документации, описаний архитектурных решений на сайте ZeroMQ, который не совсем AMQP-брокер, но общая архитектура, детали реализации представляют отдельный интерес; обзорная статья от Duncan McGregor о txAMQP и AMQP в общем (A Simfonia on Messaging with txAMQP, II, III)

Далее необходимо выбрать AMQP-брокер, который вы будете использовать. При выборе необходимо рассматривать как собственно характеристики сервера: скорость работы, надежность, легкость установки и поддержки, но также внимательно смотреть на версию AMQP-протокола, которая поддерживается брокером, – она должна совпадать с версией клиентской AMQP-библиотеки. Из брокеров я бы посоветовал RabbitMQ, написанный на Erlang, и Qpid, версии на C++ (AMQP 0-10) и Java (0-8, 0-9).

Сам протокол AMQP устроен достаточно интересно: на самом нижнем уровне определяется формат кодирования данных в бинарный вид для передачи по TCP-соединению, выше лежит формат передачи RPC-запросов между сервером и клиентом. Сама семантика работы с сообщениями, создания очередей и т.п. описывается в XML-спецификации, которая по сути задает RPC-интерфейс сервера и клиента (примеры таких XML-файлов для версий 0-8 и 0-10). Этот XML является последней и конечной спецификацией протокола. Более того, версии протокола 0-8 и 0-10 отличаются настолько сильно, что поддерживать их одновременно вряд ли возможно в одной программе. Что еще более интересно, иногда такие spec-файлы для разных брокеров AMQP, формально поддерживающих одну и ту же версию протокола, отличаются настолько, что не являются взаимозаменяемыми. Но это скорее небольшие технические проблемы.

AMQP основан на трех понятиях:

  1. Сообщение (message) – единица передаваемых данных, основная его часть (содержание) никак не интерпретируется сервером, к сообщению могут быть прицеплены структурированные заголовки.
  2. Точка обмена (exchange) – в нее отправляются сообщения. Точка обмена распределяет сообщения в одну или несколько очередей. При этом в точке обмена сообщения не хранятся. Точки обмена бывают трех типов: fanout – сообщение передается во все прицепленные к ней очереди; direct – сообщение передается в очередь с именем, совпадающим с ключом маршрутизации (routing key) (ключ маршрутизации указывается при отправке сообщения); topic – нечто среднее между fanout и exchange, сообщение передается в очереди, для которых совпадает маска на ключ маршрутизации, например, app.notification.sms.* – в очередь будут доставлены все сообщения, отправленные с ключами, начинающимися на app.notification.sms.
  3. Очередь (queue) – здесь хранятся сообщения до тех пор, пока не будет забраны клиентом. Клиент всегда забирает сообщения из одной или нескольких очередей.

Меня в AMQP привлек эффективный бинарный протокол, ориентированность протокола на минимальные задержки и гибкость настройки. Я его использовал для рассылки сообщений всем серверам кластера (fanout exchange) и организации аналогов «почтовых ящиков», в которые доставляются сообщения, адресованные определенным клиентам (direct exchange). Для получения сообщений нет необходимости опрашивать сервер, достаточно подписаться на сообщения из очереди, и сервер передаст их в тот момент, когда они появятся.

В качестве клиентской библиотеки я выбрал библиотеку txAMQP для Twisted Framework (Python). В общем и целом все работает, но где-то требуются небольшие «доделки» и «подкрутки», которые я планирую опубликовать на launchpad. В AMQP и вокруг AMQP есть много интересного и перспективного. К примеру, брокер RabbitMQ умеет масштабироваться и работать в едином кластере. Мне кажется, это очень полезная и перспективная технология.

Trackbacks

Use this link to trackback from your own site.

Comments

Leave a response

  1. Alexandre Пн, 20 Июл 2009 12:34:43 UTC

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

    реализовал экстеншен phpamqp (выложу в ближайшее время в google.code ) а также модуль ngxamqp_module для аяксовского обмена на прямую – правда код не оттестирован, и только на чтение из очереди (есть идея организовать REST) передачу бинарного контента пока не реализовал, не знаю как ее использовать, будут какие идеи – меня легко найти в яндексе

    все пока в стадии испытаний и альфа релиза проект скоро увидит свет (осень этого года)

    С наилучшими пожеланиями

    Александр Календарев

  2. Денис Баженов Пн, 03 Авг 2009 14:30:36 UTC

    Давно присматриваюсь к AMQP. Скорее в целях «расширения горизонта». Мы уже довольно долгое время используем ActiveMQ, который нас пока что устраивает.

    Но вот чего я до сих пор не могу понять, так это то, – почему AMQP становится так популярен? Это всего лишь протокол. Почему, например, OpenWire, который используется ActiveMQ не вызывает такого «шума»? Тоже хороший бинарный протокол. Дело в самом протоколе, или это profit стандартизации так привлекает людей. Ведь если посмотреть вокруг, то оказывается что есть просто масса уже отлично работающего middleware для организации асинхронных систем. А тут завоевывает популярность какая-то абстрактная идея протокола.

  3. Андрей Пн, 03 Авг 2009 19:44:48 UTC

    Денис, наверное, потому, что это не только абстрактный протокол, но и большое количество реализаций, вполне реальных. Клиентских и серверных. Всегда приятно, когда есть выбор софта без полной смены протокола и базовых сущностей.

  4. Денис Баженов Вт, 04 Авг 2009 02:10:13 UTC

    А что из реализаций есть кроме Qpid и RabbitMQ? Я почему-то больше ничего не нашел.

    Вы только поймите меня правильно, я не выступаю против AMQP. Мне, например, очень нравится идея binding’а endpoint’ов. Это многие вещи должно упростить. В отсутствии binding’а приходится пользоватся mediation routing’ом и чем-то наподобии Apache Camel (http://camel.apache.org/) для того, чтобы реализовать логику routing’а между очередями.

    Просто вся эта суета с версиями протоколов и отсутствие действительного широкого выбора брокеров (может быть, я действительно плохо искал) отпугивает от production использования. В этой связи у меня вопрос. Вы используете AMQP production, и если да, то в какой топологии? Например, ActiveMQ тоже может работать как Federated Network, но у нас в свое время (тогда еще была версия 5.0) не получилось его заставить корректно работать в такой конфигурации. Наверное, что-то не так делали.

  5. Андрей Вт, 04 Авг 2009 06:55:45 UTC

    Проблема с версиями протоколов очень серьезная. Есть проблема с семантикой операций, ошибочными ситуациями и т.п. Проблем много.

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

    Хватит выдумывать протоколы. Надо создавать открытые, взаимодействующие системы.

  6. M0sTH8 Вт, 20 Окт 2009 06:26:23 UTC

    Для Django (хотя и не только) я бы выделил хорошую библиотеку celery(http://www.celeryproject.org/), позволяющую работать по ampq с теми же RabbitMQ, ZeroMQ, Qpid.

  7. Joaquina Keas Вт, 11 Янв 2011 03:40:54 UTC

    Umschauen hat keinen Sinn -

Comments