在经纪人的activemq网络中禁用jmx可以消除有关jmx连接器注册的竞争条件.在同一台机器上启动多个activemq服务器时:
Failed to start jmx connector: Cannot bind to URL [rmi://localhost:1099/jmxrmi]: javax.naming.NameAlreadyBoundException: jmxrmi [Root exception is java.rmi.AlreadyBoundException: jmxrmi]
另一个问题是,即使不引起竞争条件,这个异常仍然可以发生.即使在等待他们在两者之间正确初始化的同时开始一个经纪人.如果一个进程由root作为第一个实例运行,另一个进程作为普通用户运行,用户进程尝试注册自己的jmx连接器,尽管已经有一个.
Failed to start jmx connector: Cannot bind to URL [rmi://localhost:1099/jmxrmi]: javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: java.net.ConnectException: Connection refused]
这些例外导致经纪人网络停止工作,或者根本不工作.
禁用jmx的技巧是,jmx必须在连接失败中被禁用.
文档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>
为此,不需要为jvm指定-Dcom.sun.management.jmxremote = false.哪个也不为我工作,因为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,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,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>
解决方法
vm://localhost?broker.persistent=false&broker.useJmx=false
broker.useJmx = false会做伎俩.