Статьи

Миграция с JMS на AMQP: RabbitMQ, Spring, Apache Camel и Apache Qpid


Как вы знаете, я с открытым исходным кодом и полностью переделываю свою докторскую систему.
Одной из моих целей было заменить внутренние очереди JMS на AMQP. Сегодня я покажу вам, как я это сделал и почему меня заставили сменить RabbitMQ на Apache Qpid.

AMQP

Вкратце. AMQP — это протокол уровня приложений открытого стандарта для промежуточного программного обеспечения, ориентированного на сообщения. Наиболее важной особенностью является то, что AMQP является протоколом проводного уровня и совместим по конструкции. JMS — это просто API. Хотя брокеры JMS могут использоваться в приложениях .NET (см. Мой пост:
ActiveMQ и .NET вместе! ), Вся спецификация JMS не гарантирует совместимость. Кроме того, стандарт AMQP по своей конструкции более гибкий и мощный (например, поддерживает двустороннюю связь по конструкции) — они просто извлекли уроки из ошибок JMS :).

О, забыл упомянуть. AMQP изначально был разработан банками :), поэтому я не должен говорить, что AMQP является безопасным, отказоустойчивым и так далее.

RabbitMQ

RabbitMQ — самый зрелый брокер AMQP. RabbitMQ написан на Erlang, поэтому сначала его нужно загрузить (установщик RabbitMQ для Windows сделает это за вас). Загрузите его отсюда:
http://www.rabbitmq.com/ .

Я также рекомендую установить консоль веб-управления. Из каталога sbin Кролика выполните:

rabbitmq-plugins enable rabbitmq_management

Если вы работаете в Windows и установили службу Rabbit, вам нужно ее перезапустить.

Вот и все.

весна

Что ж, оказалось, что VMware купила RabbitMQ, и разработчики SpringSource сейчас его разрабатывают. Учитывая этот факт, вы не должны удивляться, что интеграция Spring — RabbitMQ по-детски проста.

Добавьте зависимость Spring-Rabbit в ваш проект Maven, а затем в конфигурации Spring вставьте следующее:

<rabbit:connection-factory id="connectionFactory" />
<rabbit:template connection-factory="connectionFactory" id="amqpTemplate" routing-key="myqueue" />
<rabbit:admin connection-factory="connectionFactory" />
<rabbit:queue name="myqueue" />

Конфигурация по умолчанию предполагает, что RabbitMQ работает на локальном сервере с использованием порта по умолчанию и учетных данных по умолчанию (гость / гость). Конечно, все эти параметры настраиваются.

Чтобы отправить сообщение в очередь «myqueue», просто внедрите экземпляр AmqpTemplate в свой сервис и отправьте сообщение. Примером может быть:

@Service
public class HomeController {
    @Autowired
    private AmqpTemplate amqpTemplate;
    public void sendMessage(Bundle bundle) throws IOException {       
        byte[] body = IOUtils.toByteArray(bundle.getInputStream());
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setContentType(bundle.getContentType());
        messageProperties.setContentLength(bundle.getSize());
        messageProperties.setTimestamp(new Date());
        messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
        Message message = new Message(body, messageProperties);
        amqpTemplate.send(message);
    }
}

Вы можете открыть веб-консоль http: // localhost: 55672 / mgmt / и увидеть 1 сообщение в очереди «myqueue».

Apache Camel

Чтобы прочитать сообщение от Apache Camel, сначала нужно добавить зависимость camel-amqp в POM. Затем просто скопируйте и вставьте следующее определение маршрута:

<camelContext xmlns="http://camel.apache.org/schema/spring">
 <route>
  <from uri="amqp:queue:myqueue" />
  <to uri="log:Message" />
 </route>
</camelContext>

Запустите маршрут, выполнив
mvn:camel-runи … вы увидите ошибку.

Короче говоря, Apache Camel 2.9.0 не работает с RabbitMQ. Это связано с тем, что
camel-amqpкомпонент использует клиент Apache Qpid. Текущая версия Qpid — 0.14, но ребята из Qpid забыли загрузить новые баночки в публичное репозиторий Maven. Таким образом
camel-amqp, все еще используется Qpid 0.12, чей клиент, кажется, не согласовывает протоколы. Даже если вы исключите
qpid-commonsи
qpid-clientзависимости и явно добавите Qpid 0.14 (загрузите их и установите в локальном репо), из camel-amqpкомпонента будет сгенерировано исключение, так
как
ConnectionFactoryконструктор по умолчанию больше не существует
.

Таким образом я был вынужден установить Qpid.

Qpid

Я скачал сервер Java и просто запустил его. Консоли веб-управления нет, но это нормально. Вы можете использовать JConsole для JMX.

Spring AMQP и Qpid

Чтобы заставить Spring AMQP работать с Qpid, скопируйте и вставьте следующую конфигурацию:

<camelContext xmlns="http://camel.apache.org/schema/spring">
 <route>
  <from uri="amqp:queue:queue" />
  <to uri="log:Message" />
 </route>
</camelContext>

<bean id="amqp" class="org.apache.camel.component.amqp.AMQPComponent">
 <property name="connectionFactory" ref="amqConnectionFactory" />
</bean>

<bean id="amqConnectionFactory" class="org.apache.qpid.client.AMQConnectionFactory">
 <property name="host" value="localhost" />
 <property name="port" value="5672" />
 <property name="defaultUsername" value="guest" />
 <property name="defaultPassword" value="guest" />
 <property name="virtualPath" value="/development" />
</bean>

Как вы можете видеть в приведенном выше фрагменте, я явно создал
AMPQComponentс
connectionFactoryустановленным на Apache Qpid
AMQConnectionFactoryобъект.

Исходный код и рабочий пример

Это решение является частью проекта Qualitas. Я использую Spring MVC для обработки загрузок пакетов бизнес-процессов (например, архива в формате WS-BPEL) и отправляю его в очередь AMQP. Затем Apache Camel принимает сообщение, выполняет дополнительную обработку пакета и устанавливает его на механизм выполнения удаленного бизнес-процесса.

Проекты, которые вас больше всего интересуют:

  • qualitas-webapp (Spring MVC отправляет сообщения в AMQP)
  • qualitas-internall-Installation (маршрут Apache Camel, получающий сообщения от AMQP)

Чтобы проверить тег 0.0.2-SNAPSHOT здесь:
http://code.google.com/p/qualitas/source/browse/ .

Qualitas

Подробнее о проекте Qualitas читайте здесь:
http://code.google.com/p/qualitas/ . Рад приветствовать новых разработчиков на борту!

ура,

Лукаш