在activemq经纪人网络中禁用jmx(spring,xbean)

sub*_*bes 16 java spring activemq-classic jmx

由于我在这个问题上遇到了很多困难,所以我发布了我的解决方案.在activemq代理网络中禁用jmx会删除有关jmx连接器注册的竞争条件.在同一台计算机上启动多个activemq服务器时:

无法启动jmx连接器:无法绑定到URL [rmi:// localhost:1099/jmxrmi]:javax.naming.NameAlreadyBoundException:jmxrmi [Root exception is java.rmi.AlreadyBoundException:jmxrmi]

另一个问题是,即使您没有引起竞争条件,仍然可能发生此异常.即使在等待他们在两者之间正确初始化的同时开始一个接一个的经纪人.如果一个进程由root作为第一个实例运行而另一个进程作为普通用户运行,则用户进程会以某种方式尝试注册自己的jmx连接器,尽管已经有一个.

或者成功注册jmx连接器的代理发生故障时发生的另一个异常:

无法启动jmx连接器:无法绑定到URL [rmi:// localhost:1099/jmxrmi]:javax.naming.ServiceUnavailableException [根异常是java.rmi.ConnectException:连接拒绝主机:localhost; 嵌套异常是:java.net.ConnectException:连接被拒绝]

这些例外导致经纪人网络停止工作或根本不工作.禁用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>
Run Code Online (Sandbox Code Playgroud)

有了这个,就没有必要为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, 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>
Run Code Online (Sandbox Code Playgroud)

dao*_*way 14

可以将其他参数传递给代理URL,例如

vm://localhost?broker.persistent=false&broker.useJmx=false
Run Code Online (Sandbox Code Playgroud)

broker.useJmx = false可以解决问题.

  • 如果你得到SAXParseException - "对实体的引用"broker.useJmx"必须以';'结尾 分隔符.",然后使用_&amp; _而不是_&_ - **vm:// localhost?broker.persistent = false&amp; broker.useJmx = false** (5认同)

Jak*_*rab 2

vm:// URI 连接到一个代理,该代理的brokerName 属性与URI 中使用的属性相匹配,否则它将启动一个具有该名称的嵌入式代理。因此您可以轻松设置vm://foowhere <amq:broker brokerName="foo"/>

有时可能会出现竞争情况,即工厂在代理之前启动,然后启动嵌入式实例(请参阅 htp://activemq.apache.org/vm-transport-reference.html)。您可以通过使用 ConnectionFactory 的 Spring bean 配置中的 dependent-on 属性来解决此问题。