2010-03-27 10 views
13

Depuis que j'ai eu beaucoup de mal avec ce problème, je poste ma solution. La désactivation de jmx dans un réseau de courtiers activemq supprime les conditions de concurrence relatives à l'enregistrement du connecteur jmx. Lors du démarrage de plusieurs serveurs ActiveMQ sur la même machine:Désactiver jmx dans le réseau de courtiers activemq (spring, xbean)

Impossible de démarrer le connecteur JMX: ne peut pas se lier à l'URL [rmi: // localhost: 1099/jmxrmi]: javax.naming.NameAlreadyBoundException: jmxrmi exception [racine est java .rmi.AlreadyBoundException: jmxrmi]

un autre problème avec ceci est que même si vous ne cause pas une condition de course, cette exception peut encore se produire. Même lorsque vous démarrez un courtier après l'autre en attendant qu'ils s'initialisent correctement entre les deux. Si un processus est exécuté par root en tant que première instance et l'autre en tant qu'utilisateur normal, le processus utilisateur essaie en quelque sorte d'enregistrer son propre connecteur jmx, bien qu'il en existe déjà un.

Ou une autre exception qui se produit lorsque le courtier qui a enregistré avec succès le connecteur JMX descend:

Impossible de démarrer le connecteur JMX: Ne peut pas se lier à l'URL [rmi: // localhost: 1099/jmxrmi]: javax .naming.ServiceUnavailableException [L'exception racine est java.rmi.ConnectException: Connexion refusée à l'hôte: localhost; l'exception imbriquée est: java.net.ConnectException: connexion refusée]

Ces exceptions font que le réseau de courtiers cesse de fonctionner ou ne fonctionne pas du tout. L'astuce pour désactiver jmx était que jmx devait aussi être désactivé dans la connectionfactory. La documentation http://activemq.apache.org/jmx.html ne dit pas que cela est nécessaire explicitement. Donc, je devais lutter pour 2 jours jusqu'à ce que je trouve la solution:

<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> 

Avec cela, il n'y a pas besoin de spécifier -Dcom.sun.management.jmxremote = false pour le jvm. Ce qui n'a pas fonctionné pour moi, car connectionfactory a démarré le connecteur jmx.

Edit:

réponse Tonys m'a amené à repenser la configuration et je trouve une version simplifiée qui fonctionne également.

<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> 

Répondre

2

Le vm: // URI se connecte à un courtier dont brokerName attribut correspond à celui utilisé dans l'URI, sinon il commence un intégré avec un nom que. Donc, vous pouvez tout aussi facilement configurer vm://foo<amq:broker brokerName="foo"/>.

Il peut parfois y avoir une condition de concurrence dans laquelle la fabrique démarre avant le courtier et lance à son tour une instance incorporée (voir htp: //activemq.apache.org/vm-transport-reference.html). Vous pouvez contourner ce problème en utilisant l'attribut depends-on dans la configuration du bean Spring de ConnectionFactory.

9

Il est possible de passer paramètre supplémentaire à l'URL de courtier, comme

vm://localhost?broker.persistent=false&broker.useJmx=false 

broker.useJmx = false fera l'affaire.

+1

Si vous obtenez SAXParseException - courtier "La référence à l'entité".useJmx "doit se terminer par le ';' délimiteur. ", puis utilisez _ & _ au lieu de _ & _ - ** vm: // localhost? broker.persistent = false & broker.useJmx = false ** –

Questions connexes