2011-11-03 60 views
4

(编辑在11.11.11,编辑在底部)2个HornetQ的服务器之间的HornetQ JMS桥未能提供

我有两个JBoss应用服务器6.1的服务器上运行的HornetQ(2.2.5版本AS7)服务器。 让我们打电话给另一个CLIENT和其他一个MASTER。

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

在CLIENT和MASTER服务器之间建立了一个JMS桥接器, 消耗来自CLIENT上sourceQueue的消息,并且应该在MASTER上的目标队列的 上产生它们。该桥在CLIENT JBoss上运行。

问题:从源代码消耗并在目标上生成消息,表面上看起来似乎没有任何事情发生:消息来源有1条消息,目标没有消息。信息源也可能一遍又一遍地被反馈。

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

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

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

你会如何去诊断HornetQ桥的问题?

下面是hornetq-jboss-beans.xml中的桥接定义(在CLIENT/jboss/server/default/deploy/hornetq上)。定义是HornetQ manual的JMS桥例子十分相近:

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

而且在主机侧将hornetq-jms.xml文件:

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

编辑: 出于某种原因,桥上开始,如果我停下来,水库transfering消息在两台服务器完全部署后立即启动桥接。这是一个手动过程,我不喜欢使用黑客来定期重新启动网桥。我欢迎对此问题提出任何建议。

我还改进了启动顺序,使网桥依赖于它从中读取的队列 - 否则网桥会在队列之前启动,从而导致错误记录。

+0

请发布核心队列配置示例以及声明核心桥和核心队列之间依赖关系的方式。在此先感谢 –

+1

为了使JMS桥开始“之后的” JMS服务器准备就绪后,把 JMSServerManager 的JMSBridge bean定义的之前有权根据HornetQ的例子(JMS/JMS桥) –

回答

0

为什么不使用核心桥?

+0

使用核心桥需要使用核心队列,并且它们必须存在于桥之前。我无法弄清楚如何将核心队列作为JMS队列公开,HornetQ论坛上的响应也不像那个解决方案那样令人鼓舞。如果你有解决方案,我会非常乐意使用核心桥梁。 –

+1

现在已经用JMS桥解决了这个问题。后来我遇到了一个似乎解决了这个问题的提示。必须处理命名约定:核心队列会得到您给他们的确切名称。 JMS队列有“jms.queue”。预先给予你给他们的名字。为了使用具有JMS访问队列的核心网桥,需要在名称为“jms.queue.QUEUENAME”的情况下引用核心队列,而在jms配置中则引用“QUEUENAME”。这还没有经过测试,但看起来可能会起作用。 –