Статьи

Встроенный брокер ActiveMQ с Mule

В этой статье я покажу, как встроенный брокер ActiveMQ автоматически запускается при использовании URL-адреса посредника «vm: // localhost» в соединителе Mule JMS без какой-либо дополнительной настройки, и как отключить это поведение. Я также расскажу, как явно настроить встроенный брокер ActiveMQ в файле конфигурации Mule.

Как указано в документации Mule в разделе Интеграция ActiveMQ , Mule автоматически запускает встроенный экземпляр ActiveMQ, если для JMS-коннектора ActiveMQ задан URL-адрес посредника, равный «vm: // localhost». То же самое верно, если создается обычный JMS-соединитель со ссылкой на фабрику соединений ActiveMQ с указанным выше URL-адресом.
Это поведение можно проверить с помощью следующих шагов:

  • Создайте проект Mule в IDE с установленным плагином Mule Studio.
  • Добавьте JAR-файл ActiveMQ-all в путь к библиотеке нового проекта.
  • В src / main / resources нового проекта создайте файл с именем «log4j.xml» со ​​следующим содержимым:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
    <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
        <param name="Target" value="System.out" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %-5p %-30C - %m%n" />
        </layout>
    </appender>
    
    <logger name="org.mule">
        <level value="INFO"/>
    </logger>
    
    <logger name="org.apache.activemq">
        <level value="INFO"/>
    </logger>
    
    <root>
        <priority value="WARN" />
        <appender-ref ref="stdout" />
    </root>
</log4j:configuration>

Вставьте следующее в файл конфигурации Mule нового проекта:

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns="http://www.mulesoft.org/schema/mule/core"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:spring="http://www.springframework.org/schema/beans"
    xmlns:jms="http://www.mulesoft.org/schema/mule/jms"
    xmlns:amq="http://activemq.apache.org/schema/core"
    xmlns:test="http://www.mulesoft.org/schema/mule/test"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/jms http://www.mulesoft.org/schema/mule/jms/current/mule-jms.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd
http://www.mulesoft.org/schema/mule/test http://www.mulesoft.org/schema/mule/test/current/mule-test.xsd" version="CE-3.4.0">

    <spring:beans>
        <spring:bean name="amq-connection-factory"
            class="org.apache.activemq.ActiveMQConnectionFactory">
            <spring:property name="brokerURL" value="vm://localhost"/>
        </spring:bean>
    </spring:beans>
    
    <jms:connector name="my-jms-connector"
        connectionFactory-ref="amq-connection-factory"
        specification="1.1">
    </jms:connector>
</mule>
  • Щелкните правой кнопкой мыши файл конфигурации Mule и выберите Run As -> Mule Application.
  • Остановите приложение Mule.

Глядя на вывод журнала в консоли, можно наблюдать следующее:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Starting app 'testembeddedjms'                           +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2014-06-26 14:53:46,385 INFO  org.mule.module.logging.DispatchingLogger - Starting ResourceManager
2014-06-26 14:53:46,387 INFO  org.mule.module.logging.DispatchingLogger - Started ResourceManager
2014-06-26 14:53:46,496 INFO  org.mule.module.logging.DispatchingLogger - Loaded the Bouncy Castle security provider.
2014-06-26 14:53:46,611 INFO  org.mule.module.logging.DispatchingLogger - JMX consoles can connect to service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi
2014-06-26 14:53:46,657 INFO  org.mule.module.logging.DispatchingLogger - PListStore:[/Volumes/BigHD/Development/Workspace/testembeddedjms/activemq-data/localhost/tmp_storage] started
2014-06-26 14:53:46,661 INFO  org.mule.module.logging.DispatchingLogger - Using Persistence Adapter: KahaDBPersistenceAdapter[/Volumes/BigHD/Development/Workspace/testembeddedjms/activemq-data/localhost/KahaDB]
2014-06-26 14:53:46,868 INFO  org.mule.module.logging.DispatchingLogger - KahaDB is version 5
2014-06-26 14:53:46,879 INFO  org.mule.module.logging.DispatchingLogger - Recovering from the journal ...
2014-06-26 14:53:46,882 INFO  org.mule.module.logging.DispatchingLogger - Recovery replayed 29 operations from the journal in 0.011 seconds.
2014-06-26 14:53:47,031 INFO  org.mule.module.logging.DispatchingLogger - Apache ActiveMQ 5.9.1 (localhost, ID:computer.lan-12345-123456789-0:1) is starting
2014-06-26 14:53:47,036 INFO  org.mule.module.logging.DispatchingLogger - Apache ActiveMQ 5.9.1 (localhost, ID:computer.lan-12345-123456789-0:1) started
2014-06-26 14:53:47,036 INFO  org.mule.module.logging.DispatchingLogger - For help or more information please see: http://activemq.apache.org
2014-06-26 14:53:47,062 INFO  org.mule.module.logging.DispatchingLogger - Connector vm://localhost started
2014-06-26 14:53:47,070 INFO  org.mule.module.logging.DispatchingLogger - Connected: JmsConnector

Как видно из строк 13 и 14, запускается экземпляр ActiveMQ. Это поведение реализовано в классе ActiveMQ org.apache.activemq.transport.vm.VMTransportFactory и, таким образом, не является чем-то, что контролирует Mule.
В некоторых случаях может быть желательно не запускать встроенный ActiveMQ автоматически, например, если об этом позаботится другая часть приложения. Это можно сделать, добавив параметр «create = false» в URL-адрес брокера.
Модифицированный файл конфигурации Mule выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns="http://www.mulesoft.org/schema/mule/core"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:spring="http://www.springframework.org/schema/beans"
    xmlns:jms="http://www.mulesoft.org/schema/mule/jms"
    xmlns:amq="http://activemq.apache.org/schema/core"
    xmlns:test="http://www.mulesoft.org/schema/mule/test"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/jms http://www.mulesoft.org/schema/mule/jms/current/mule-jms.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd
http://www.mulesoft.org/schema/mule/test http://www.mulesoft.org/schema/mule/test/current/mule-test.xsd" version="CE-3.4.0">

    <spring:beans>
        <spring:bean name="amq-connection-factory"
            class="org.apache.activemq.ActiveMQConnectionFactory">
            <spring:property name="brokerURL" value="vm://localhost?create=false"/>
        </spring:bean>
    </spring:beans>
    
    <jms:connector name="my-jms-connector"
        connectionFactory-ref="amq-connection-factory"
        specification="1.1">
    </jms:connector>
</mule>

Если мы теперь запустим приложение Mule снова, результатом будет исключение, говорящее, что нет никакого брокера с именем «localhost»:

Exception in thread "main" org.mule.module.launcher.DeploymentStartException: IOException: Broker named 'localhost' does not exist.
    at org.mule.module.launcher.application.DefaultMuleApplication.start(DefaultMuleApplication.java:170)
    at org.mule.module.launcher.application.ApplicationWrapper.start(ApplicationWrapper.java:107)
    at org.mule.module.launcher.DefaultMuleDeployer.deploy(DefaultMuleDeployer.java:48)
    at org.mule.tooling.server.application.ApplicationDeployer.run(ApplicationDeployer.java:58)
    at org.mule.tooling.server.application.ApplicationDeployer.main(ApplicationDeployer.java:91)

Чтобы исправить эту ошибку и предположить, что требуется больший контроль над встроенным экземпляром ActiveMQ, файл конфигурации Mule снова изменяется, чтобы включить встроенный брокер ActiveMQ. Результат выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns="http://www.mulesoft.org/schema/mule/core"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:spring="http://www.springframework.org/schema/beans"
    xmlns:jms="http://www.mulesoft.org/schema/mule/jms"
    xmlns:amq="http://activemq.apache.org/schema/core"
    xmlns:test="http://www.mulesoft.org/schema/mule/test"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/jms http://www.mulesoft.org/schema/mule/jms/current/mule-jms.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd
http://www.mulesoft.org/schema/mule/test http://www.mulesoft.org/schema/mule/test/current/mule-test.xsd" version="CE-3.4.0">

    <spring:beans>
        <amq:broker id="amq-broker"
            useJmx="false"
            persistent="false"
            restartAllowed="false"
            useShutdownHook="true"
            startAsync="true">
            <amq:destinationPolicy>
                <amq:policyMap>
                    <amq:policyEntries>
                        <amq:policyEntry queue=">" producerFlowControl="true" memoryLimit="1mb">
                            <amq:deadLetterStrategy>
                                <amq:individualDeadLetterStrategy
                                    queuePrefix="DLQ." useQueueForQueueMessages="true" />
                            </amq:deadLetterStrategy>
                        </amq:policyEntry>
                    </amq:policyEntries>
                </amq:policyMap>
            </amq:destinationPolicy>
            <amq:transportConnectors>
                <amq:transportConnector uri="vm://localhost"/>
            </amq:transportConnectors>
        </amq:broker>
    
        <spring:bean name="amqRedeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">
            <spring:property name="maximumRedeliveries" value="-1"/>
            <spring:property name="initialRedeliveryDelay" value="500"/>
            <spring:property name="useExponentialBackOff" value="false"/>
            <spring:property name="backOffMultiplier" value="5"/>
            <spring:property name="maximumRedeliveryDelay" value="-1"/>
        </spring:bean>
        
        <spring:bean name="amq-connection-factory"
            class="org.apache.activemq.ActiveMQConnectionFactory"
            depends-on="amq-broker">
            <spring:property name="brokerURL" value="vm://localhost?create=false"/>
        </spring:bean>
    </spring:beans>
    
    <jms:connector name="my-jms-connector"
        connectionFactory-ref="amq-connection-factory"
        specification="1.1">
    </jms:connector>
</mule>

Поскольку элемент <amq: broker> используется для определения встроенного брокера ActiveMQ, нам также необходимо добавить библиотеку xbean-spring в путь к классам проекта. Соответствующую версию этой библиотеки можно скачать по этой ссылке .
Для получения дополнительной информации о том, как настроить ActiveMQ с использованием конфигурации XML, обратитесь к документации ActiveMQ .

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

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Starting app 'testembeddedjms'                           +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2014-06-26 15:17:28,392 INFO  org.mule.module.logging.DispatchingLogger - Starting ResourceManager
2014-06-26 15:17:28,394 INFO  org.mule.module.logging.DispatchingLogger - Started ResourceManager
2014-06-26 15:17:28,457 INFO  org.mule.module.logging.DispatchingLogger - Connector vm://localhost started
2014-06-26 15:17:28,459 INFO  org.mule.module.logging.DispatchingLogger - Apache ActiveMQ 5.9.1 (localhost, ID:computer.lan-12345-123456789-0:2) is starting
2014-06-26 15:17:28,471 INFO  org.mule.module.logging.DispatchingLogger - Connected: JmsConnector
{
  name=my-jms-connector
  lifecycle=initialise
  this=12345678
  numberOfConcurrentTransactedReceivers=4
  createMultipleTransactedReceivers=true
  connected=true
  supportedProtocols=[jms]
  serviceOverrides=<none>
}

В строке 7 приведенного выше фрагмента журнала мы видим, что внедренный экземпляр ActiveMQ (снова) запущен.

Наконец, я просто хочу добавить, что параметр «create = false» не требуется, если вы просто хотите настроить встроенный брокер ActiveMQ в приложении Mule — ActiveMQ достаточно умен, чтобы не запускать второй экземпляр брокера, если он уже существует в тот же хост
Кроме того, автоматический запуск встроенного экземпляра посредника относится только к ActiveMQ и не будет происходить при использовании других посредников JMS с Mule, если только он не реализован посредником.