В этой статье я покажу, как встроенный брокер 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, если только он не реализован посредником.