在代理的 activemq 网络中禁用 jmx(spring,xbean)编辑:
由于我在这个问题上挣扎了很多,所以我发布了我的解决方案。在代理的 activemq 网络中禁用 jmx 将删除有关 jmx 连接器注册的争用条件。在同一台机器上启动多个 activemq 服务器时:
无法启动 jmx 连接器: 无法绑定到 URL [rmi://localhost:1099/jmxrmi]: javax.name.NameAlreadyBoundException: jmxrmi [Root exception is java.rmi.AlreadyBoundException: jmxrmi]
这样做的另一个问题是,即使您不导致争用条件,此异常仍然可能发生。即使一个接一个地启动代理,同时等待它们在此期间正确初始化。如果一个进程由 root 作为第一个实例运行,另一个进程作为普通用户运行,则用户进程会以某种方式尝试注册自己的 jmx 连接器,尽管已经存在一个。
或者,当成功注册 jmx 连接器的代理出现故障时,会发生另一个异常:
无法启动 jmx 连接器: 无法绑定到 URL [rmi://localhost:1099/jmxrmi]: javax.nameing.ServiceUnavailableException [根异常是 java.rmi.ConnectException: 连接被拒绝主机: localhost; 嵌套异常是: java.net.ConnectException: 连接被拒绝]
这些异常会导致代理网络停止工作,或者根本无法工作。禁用 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。不知何故,这对我来说也不起作用,因为连接工厂启动了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>