Ответ 1
Возможно передать дополнительный параметр URL-адресу брокера, например
vm://localhost?broker.persistent=false&broker.useJmx=false
broker.useJmx = false сделает трюк.
Поскольку я много боролся с этой проблемой, я отправляю свое решение. Отключение jmx в сети брокеры activemq устраняет условия гонки по поводу регистрации соединителя jmx. При запуске нескольких серверов activemq на одном компьютере:
Не удалось запустить jmx-коннектор: не удается привязать к URL [rmi://localhost: 1099/jmxrmi]: javax.naming.NameAlreadyBoundException: jmxrmi [Исключение корня java.rmi.AlreadyBoundException: jmxrmi]
Другая проблема заключается в том, что даже если вы не вызываете условие гонки, это исключение все равно может произойти. Даже при запуске одного брокера за другим, ожидая их правильной инициализации между ними. Если один процесс запускается как первый экземпляр, а другой - как обычный пользователь, пользовательский процесс пытается зарегистрировать свой собственный jmx-коннектор, хотя он уже есть.
Или другое исключение, которое происходит, когда брокер, успешно зарегистрировавший соединитель jmx, падает:
Не удалось подключиться к jmx-коннектору: не удается привязать к URL-адресу [rmi://localhost: 1099/jmxrmi]: javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: подключение отказалось от хоста: localhost; вложенное исключение: java.net.ConnectException: соединение отклонено]
Эти исключения заставляют сеть брокеров перестать работать или вообще не работать. Трюк для отключения jmx состоял в том, что jmx также должен был быть отключен в connectionfactory. Документация http://activemq.apache.org/jmx.html не говорит, что это необходимо явно. Поэтому мне пришлось бороться за 2 дня, пока не нашел решение:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core-5.3.1.xsd">
<!-- Spring JMS Template -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<constructor-arg ref="connectionFactory" />
</bean>
<!-- Caching, sodass das jms template überhaupt nutzbar ist in sachen performance -->
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<constructor-arg ref="amqConnectionFactory" />
<property name="exceptionListener" ref="jmsExceptionListener" />
<property name="sessionCacheSize" value="1" />
</bean>
<!--
Jeder Client verbindet sich mit seinem eigenen broker, broker sind untereinander vernetzt. Nur wenn hier
nochmals jmx deaktiviert wird, bleibt es auch deaktiviert...
-->
<amq:connectionFactory id="amqConnectionFactory" brokerURL="vm://broker:default?useJmx=false" />
<!--
Broker suchen sich einen eigenen Port und sind gegenseitig verbunden, ergeben dadurch ein Grid. Dies zwar etwas
langsamer, aber dafür ausfallsicherer. Siehe http://activemq.apache.org/networks-of-brokers.html
-->
<amq:broker useJmx="false" persistent="false">
<!-- Wird benötigt um JMX endgültig zu deaktivieren -->
<amq:managementContext>
<amq:managementContext connectorHost="localhost" createConnector="false" />
</amq:managementContext>
<!-- Nun die normale Konfiguration für Network of Brokers -->
<amq:networkConnectors>
<amq:networkConnector networkTTL="1" duplex="true" dynamicOnly="true" uri="multicast://default" />
</amq:networkConnectors>
<amq:persistenceAdapter>
<amq:memoryPersistenceAdapter />
</amq:persistenceAdapter>
<amq:transportConnectors>
<amq:transportConnector uri="tcp://localhost:0" discoveryUri="multicast://default" />
</amq:transportConnectors>
</amq:broker>
</beans>
При этом нет необходимости указывать -Dcom.sun.management.jmxremote = false для jvm. Что-то также не работало для меня, потому что connectionfactory запустил jmx-коннектор.
Ответ Tonys привел меня к переосмыслению конфигурации, и я нашел упрощенную версию, которая также работает.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core-5.3.2.xsd">
<!-- Caching, sodass das jms template überhaupt nutzbar ist in sachen performance -->
<bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<constructor-arg ref="amqConnectionFactory" />
<property name="exceptionListener" ref="jmsExceptionListener" />
<property name="sessionCacheSize" value="1" />
</bean>
<!--
Jeder Client verbindet sich mit seinem eigenen broker, broker sind untereinander vernetzt. Nur wenn hier nochmals jmx
deaktiviert wird, bleibt es auch deaktiviert...
-->
<amq:connectionFactory id="amqConnectionFactory" brokerURL="vm://default?broker.persistent=false" />
<!--
Broker suchen sich einen eigenen Port und sind gegenseitig verbunden, ergeben dadurch ein Grid. Dies zwar etwas
langsamer, aber dafür ausfallsicherer. Siehe http://activemq.apache.org/networks-of-brokers.html
-->
<amq:broker useJmx="false" persistent="false">
<amq:networkConnectors>
<amq:networkConnector networkTTL="1" conduitSubscriptions="true" duplex="true" dynamicOnly="true"
uri="multicast://default" />
</amq:networkConnectors>
<amq:persistenceAdapter>
<amq:memoryPersistenceAdapter />
</amq:persistenceAdapter>
<amq:transportConnectors>
<amq:transportConnector uri="tcp://localhost:0" discoveryUri="multicast://default" />
</amq:transportConnectors>
</amq:broker>
Возможно передать дополнительный параметр URL-адресу брокера, например
vm://localhost?broker.persistent=false&broker.useJmx=false
broker.useJmx = false сделает трюк.
Um://URI соединяется с брокером, чей атрибут brokerName соответствует тому, который используется в URI, иначе он начинает внедренный с именем. Таким образом, вы можете легко настроить vm://foo
где <amq:broker brokerName="foo"/>
.
Иногда может быть состояние гонки, когда factory начинается перед брокером и, в свою очередь, запускает внедренный экземпляр (см. htp://activemq.apache.org/vm-transport-reference.html). Вы можете обойти это, используя атрибут зависимости в конфигурации ConnectionFactory Spring bean.