Od czasu, gdy bardzo zmagałem się z tym problemem, zamieszczam moje rozwiązanie. Wyłączenie jmx w sieci brokerów activemq powoduje usunięcie warunków wyścigu dotyczących rejestracji złącza jmx. Podczas uruchamiania wielu serwerów ActiveMQ na tej samej maszynie:Wyłącz jmx w sieci brokerów aktywnych (wiosna, xbean)
udało się uruchomić jmx złącze: nie może wiązać się z zawartości [RMI: // localhost: 1099/jmxrmi]: javax.naming.NameAlreadyBoundException: jmxrmi [wyjątek głównej JAVA .rmi.AlreadyBoundException: jmxrmi]
Kolejny problem polega na tym, że nawet jeśli nie spowoduje to wyścigu, ten wyjątek może nadal występować. Nawet przy uruchamianiu jednego brokera po drugim, podczas oczekiwania na właściwe zainicjowanie pomiędzy nimi. Jeśli jeden proces jest uruchamiany przez root jako pierwsza instancja, a drugi jako zwykły użytkownik, w jakiś sposób proces użytkownika próbuje zarejestrować własne złącze jmx, chociaż już istnieje.
Albo inny wyjątek, który się dzieje, gdy pośrednik, który z powodzeniem zarejestrowana złącze JMX idzie w dół:
powiodło się JMX złącza: Nie można powiązać do adresu [RMI: // localhost: 1099/jmxrmi]: javax .naming.ServiceUnavailableException [Główny wyjątek to java.rmi.ConnectException: Connection odmawia hosta: localhost; Zagnieżdżony wyjątek to: java.net.ConnectException: odmówiono połączenia]
Wyjątki te powodują, że sieć brokerów przestaje działać lub w ogóle nie działa. Sztuczka do wyłączenia jmx polegała na tym, że jmx musiał być wyłączony także w bibliotece połączeń. Dokumentacja http://activemq.apache.org/jmx.html nie mówi, że jest to potrzebne jawnie. Więc musiałem walczyć na 2 dni, aż znalazłem rozwiązanie:
<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>
Dzięki temu nie ma potrzeby, aby określić -Dcom.sun.management.jmxremote = false dla JVM. Co w jakiś sposób też nie zadziałało, ponieważ connectfactory uruchomił złącze jmx.
Edit:
Tonys odpowiedź doprowadziła mnie do przemyślenia konfigurację i znalazłem uproszczoną wersję, która działa również.
<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>
Jeśli otrzymasz SAXParseException - broker "odniesienia do encji".useJmx "musi kończyć się znakiem"; " delimiter. ", a następnie użyj _ & _ zamiast _ & _ - ** vm: // localhost? broker.persistent = false & broker.useJmx = false ** –