java 在 activemq 代理网络中禁用 jmx(spring、xbean)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2529340/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Disable jmx in activemq network of brokers (spring, xbean)
提问by subes
Since I've struggled a lot with this problem, I am posting my solution. Disabling jmx in an activemq network of brokers removes race conditions about the registration of the jmx connector. When starting multiple activemq servers on the same machine:
由于我在这个问题上挣扎了很多,所以我发布了我的解决方案。在 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]
无法启动 jmx 连接器:无法绑定到 URL [rmi://localhost:1099/jmxrmi]: javax.naming.NameAlreadyBoundException: jmxrmi [Root exception is java.rmi.AlreadyBoundException: jmxrmi]
Another problem with this is, that even if you don't cause a race condition, this exception can still occur. Even when starting one broker after another while waiting for them to initialize properly in between. If one process is run by root as the first instance and the other as a normal user, somehow the user process tries to register its own jmx connector, though there already is one.
另一个问题是,即使您没有导致竞争条件,此异常仍然可能发生。即使在等待它们之间正确初始化的同时启动一个又一个代理。如果一个进程由 root 作为第一个实例运行,另一个作为普通用户运行,则用户进程以某种方式尝试注册自己的 jmx 连接器,尽管已经有一个。
Or another exception which happens when the broker that successfully registered the jmx connector goes down:
或者当成功注册 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 连接器:无法绑定到 URL [rmi://localhost:1099/jmxrmi]:javax.naming.ServiceUnavailableException [Root 异常是 java.rmi.ConnectException:连接被拒绝到主机:localhost;嵌套异常是:java.net.ConnectException:连接被拒绝]
Those exceptions cause the network of brokers to stop working, or to not work at all. The trick to disable jmx was, that jmx had to be disabled in the connectionfactory aswell. The documentation http://activemq.apache.org/jmx.htmldoes not say that this is needed explicitly. So I had to struggle for 2 days until I found the solution:
这些异常会导致经纪人网络停止工作,或者根本不工作。禁用 jmx 的技巧是,也必须在 connectionfactory 中禁用 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>
With this, there is no need to specify -Dcom.sun.management.jmxremote=false for the jvm. Which somehow also didn't work for me, because the connectionfactory started the jmx connector.
有了这个,就不需要为 jvm 指定 -Dcom.sun.management.jmxremote=false。不知何故,这对我也不起作用,因为 connectionfactory 启动了 jmx 连接器。
Edit:
编辑:
Tonys answer brought me to rethinking the configuration and I found a simplified version which works aswell.
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>
回答by daoway
It's possible to pass additional parameter to broker URL, like
可以将附加参数传递给代理 URL,例如
vm://localhost?broker.persistent=false&broker.useJmx=false
broker.useJmx=false will do the trick.
broker.useJmx=false 可以解决问题。
回答by Jakub Korab
The vm:// URI connects to a broker whose brokerName attribute matches the one used in the URI, otherwise it starts an embedded one with than name. So you could just as easily set up vm://foowhere <amq:broker brokerName="foo"/>.
vm:// URI 连接到一个代理,其 brokerName 属性与 URI 中使用的那个属性匹配,否则它会以比名称开始一个嵌入的代理。因此,您可以轻松地设置vm://foowhere <amq:broker brokerName="foo"/>。
There may sometimes be a race condition where the factory starts before the broker and in turn starts an embedded instance (see htp://activemq.apache.org/vm-transport-reference.html). You can get around this by using the depends-on attribute in the ConnectionFactory's Spring bean configuration.
有时可能存在竞争条件,即工厂在代理之前启动,然后启动嵌入式实例(请参阅 htp://activemq.apache.org/vm-transport-reference.html)。您可以通过使用 ConnectionFactory 的 Spring bean 配置中的依赖属性来解决这个问题。

