jms - 两个 HornetQ 服务器之间的 HornetQ JMS 桥无法交付

标签 jms jboss6.x hornetq

(在 11.11.11 编辑,底部编辑)

我有两个运行 HornetQ(2.2.5 AS7 版)服务器的 JBoss AS 6.1 服务器。
让我们称另一个为 CLIENT,另一个为 MASTER。

CLIENT 有一个队列(“sourceQueue”),由我们的 Web 应用程序写入。

在 CLIENT 和 MASTER 服务器之间建立了一个 JMS 桥,
它使用来自 CLIENT 上的 sourceQueue 的消息,并且应该在
MASTER 上的 targetQueue。网桥在 CLIENT JBoss 上运行。

问题:不是从源中消费并在目标上产生消息,表面上似乎什么也没有发生:源有 1 条消息,目标没有。源也有可能一遍又一遍地接收该消息。

使用 netty 连接器的网络连接正在工作,这已经过测试重新启动网桥并观察 netstat -n -c 输出。

什么样的问题会导致这样的问题?

  • 网络问题?
  • 交易经理?
  • 连接器错误?

  • 您将如何诊断 HornetQ 网桥的问题?

    下面是 hornetq-jboss-beans.xml 上的网桥定义(在 CLIENT/jboss/server/default/deploy/hornetq 上)。定义是 HornetQ manual 上 JMS 桥接示例的紧密变体:
       <bean name="JMSBridge" class="org.hornetq.jms.bridge.impl.JMSBridgeImpl">
               <!-- HornetQ must be started before the bridge -->
               <depends>HornetQServer</depends>
               <constructor>
                   <!-- Source ConnectionFactory Factory -->
                   <parameter>
                       <inject bean="SourceCFF"/>
                   </parameter>
                   <!-- Target ConnectionFactory Factory -->
                   <parameter>
                       <inject bean="TargetCFF"/>
                   </parameter>
                   <!-- Source DestinationFactory -->
                   <parameter>
                       <inject bean="SourceDestinationFactory"/>
                   </parameter>
                   <!-- Target DestinationFactory -->
                   <parameter>
                       <inject bean="TargetDestinationFactory"/>
                   </parameter>
                   <!-- Source User Name (no username here) -->
                   <parameter><null /></parameter>
                   <!-- Source Password (no password here)-->
                   <parameter><null /></parameter>
                   <!-- Target User Name (no username here)-->
                   <parameter><null /></parameter>
                   <!-- Target Password (no password here)-->
                   <parameter><null /></parameter>
                   <!-- Selector -->
                   <parameter><null /></parameter>
                   <!-- Failure Retry Interval (in ms) -->
                   <parameter>5000</parameter>
                   <!-- Max Retries -->
                   <parameter>10</parameter>
                   <!-- Quality Of Service -->
                   <parameter>ONCE_AND_ONLY_ONCE</parameter>
                   <!-- Max Batch Size -->
                   <parameter>1</parameter>
                   <!-- Max Batch Time (-1 means infinite) -->
                   <parameter>-1</parameter>
                   <!-- Subscription name (no subscription name here)-->
                   <parameter><null /></parameter>
                   <!-- Client ID  (no client ID here)-->
                   <parameter><null /></parameter>
                   <!-- Add MessageID In Header -->
                   <parameter>true</parameter>
                   <!-- register the JMS Bridge in the AS MBeanServer -->
                   <parameter>
                       <inject bean="MBeanServer"/>
                   </parameter>
                   <parameter>org.hornetq:service=MyJMSBridge</parameter>
                 </constructor>
               <property name="transactionManager">
                   <inject bean="RealTransactionManager"/>
               </property>
           </bean>
    
           <!-- SourceCFF describes the ConnectionFactory used to connect to the
                source destination -->
           <bean name="SourceCFF"
                class="org.hornetq.jms.bridge.impl.JNDIConnectionFactoryFactory">
               <constructor>
                   <parameter>
                       <inject bean="sourceJNDI" />
                   </parameter>
                   <parameter>/XAConnectionFactory</parameter>
               </constructor>
           </bean>
    
           <!-- TargetCFF describes the ConnectionFactory used to connect to the
            target destination -->
           <bean name="TargetCFF"
                class="org.hornetq.jms.bridge.impl.JNDIConnectionFactoryFactory">
               <constructor>
                   <parameter>
                       <inject bean="targetJNDI" />
                   </parameter>
                   <parameter>/integration/XAConnectionFactory</parameter>
               </constructor>
           </bean>
    
           <!-- SourceDestinationFactory describes the Destination used as the source -->
           <bean name="SourceDestinationFactory"
                class="org.hornetq.jms.bridge.impl.JNDIDestinationFactory">
               <constructor>
                   <parameter>
                      <inject bean="sourceJNDI"/>
                   </parameter>
                   <parameter>/jms/notificationRequestQueue</parameter>
               </constructor>
           </bean>
    
           <!-- TargetDestinationFactory describes the Destination used as the target -->
           <bean name="TargetDestinationFactory"
                class="org.hornetq.jms.bridge.impl.JNDIDestinationFactory">
               <constructor>
                   <parameter>
                       <inject bean="targetJNDI" />
                   </parameter>
                   <parameter>/integration/jms/notificationRequestQueue</parameter>
               </constructor>
           </bean>
    
           <!-- JNDI is a Hashtable containing the JNDI properties required -->
           <!-- to connect to the sources and targets JMS resrouces         -->
          <bean name="sourceJNDI" class="java.util.Hashtable">
             <constructor class="java.util.Map">
                <map class="java.util.Hashtable" keyClass="java.lang.String"
                                                 valueClass="java.lang.String">
                   <entry>
                      <key>java.naming.factory.initial</key>
                      <value>org.jnp.interfaces.NamingContextFactory</value>
                   </entry>
                   <entry>
                      <key>java.naming.provider.url</key>
                      <value>jnp://localhost:1099</value>
                   </entry>
                   <entry>
                      <key>java.naming.factory.url.pkgs</key>
                      <value>org.jboss.naming:org.jnp.interfaces"</value>
                   </entry>
                   <entry>
                      <key>jnp.timeout</key>
                      <value>5000</value>
                   </entry>
                   <entry>
                      <key>jnp.sotimeout</key>
                      <value>5000</value>
                   </entry>
                </map>
             </constructor>
          </bean>
          <bean name="targetJNDI" class="java.util.Hashtable">
             <constructor class="java.util.Map">
                <map class="java.util.Hashtable" keyClass="java.lang.String"
                                                 valueClass="java.lang.String">
                   <entry>
                      <key>java.naming.factory.initial</key>
                      <value>org.jnp.interfaces.NamingContextFactory</value>
                   </entry>
                   <entry>
                      <key>java.naming.provider.url</key>
                      <value>jnp://TARGET-URL.example.com:1099</value>
                   </entry>
                   <entry>
                      <key>java.naming.factory.url.pkgs</key>
                      <value>org.jboss.naming:org.jnp.interfaces"</value>
                   </entry>
                   <entry>
                      <key>jnp.timeout</key>
                      <value>5000</value>
                   </entry>
                   <entry>
                      <key>jnp.sotimeout</key>
                      <value>5000</value>
                   </entry>
                </map>
             </constructor>
          </bean>
    

    客户端 hornetq-jms.xml 上的队列定义:
    <configuration xmlns="urn:hornetq"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
    
       <connection-factory name="NettyConnectionFactory">
          <connectors>
             <connector-ref connector-name="netty"/>
          </connectors>
          <entries>
             <entry name="/ConnectionFactory"/>
             <entry name="/XAConnectionFactory"/>
          </entries>
          <xa>true</xa>
       </connection-factory>
    
       <queue name="DLQ">
          <entry name="/queue/DLQ"/>
       </queue>
    
       <queue name="ExpiryQueue">
          <entry name="/queue/ExpiryQueue"/>
       </queue>
    
       <queue name="notificationQueue">
          <entry name="/jms/notificationRequestQueue"/>
       </queue>
    </configuration>
    

    在 MASTER 端 hornetq-jms.xml:
    <configuration xmlns="urn:hornetq"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
    
       <connection-factory name="NettyConnectionFactory">
          <connectors>
             <connector-ref connector-name="netty"/>
          </connectors>
          <entries>
             <entry name="/ConnectionFactory"/>
             <entry name="/XAConnectionFactory"/>
          </entries>
          <xa>true</xa>
       </connection-factory>
       <connection-factory name="NettyRemoteConnectionFactory">
          <connectors>
             <connector-ref connector-name="netty-remote"/>
          </connectors>
          <entries>
             <entry name="/integration/XAConnectionFactory"/>
          </entries>
          <xa>true</xa>
       </connection-factory>
    
       <queue name="DLQ">
          <entry name="/queue/DLQ"/>
       </queue>
    
       <queue name="ExpiryQueue">
          <entry name="/queue/ExpiryQueue"/>
       </queue>
    
       <queue name="targetQueue">
          <entry name="/integration/jms/notificationRequestQueue"/>
       </queue>
    
        <topic name="unrelatedTopic">
            <entry name="/topic/cacheFlushNotification"/>
        </topic>
    </configuration>
    

    编辑:
    出于某种原因,如果我在两台服务器完全部署后停止并重新启动桥,桥就会开始传输消息。这是一个手动过程,我讨厌使用 hack 来定期重新启动网桥。我欢迎对此问题提出任何建议。

    我还通过使桥依赖于它读取的队列来改进启动顺序 - 否则桥在队列之前启动,导致错误记录。

    最佳答案

    检查这个帖子:
    https://issues.jboss.org/browse/HORNETQ-247
    它提供了一些关于如何公开核心队列并在核心桥接中使用它们的见解。

    关于jms - 两个 HornetQ 服务器之间的 HornetQ JMS 桥无法交付,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7995625/

    相关文章:

    java - Camel 向 OracleAQ 发送消息问题

    java - 如何知道监听器是否收到 JMS 中的消息?

    java - Apache ActiveMQ Artemis 客户端可以连接到现有的 ActiveMQ "Classic"5.15.x 代理吗?

    java - 如何在 Java 中使用 Log4j 逐步配置 jboss 6.x 中的日志记录

    security - ActiveMQ 和客户端通过证书身份验证身份

    java - Wildfly 13和EJB 2.1兼容性问题和RelativeContext Classcast问题

    jboss6.x - JBoss 6.1应用程序服务器启动问题:Module not found exception

    hornetq - 如何在 HornetQ 中以编程方式创建 JMS 主题和队列?

    java-native-interface - 如何在 cmake 上使用 FIND_JNI

    jms - HornetQ核心API与JMS的性能对比