3.2.7.3. 创建 JMS 桥
概况
JMS 桥消费源 JMS 队列或主题里的消息并发送到目标 JMS 队列或主题(通常位于不同的服务器上)。它可以用于桥接 任何 JMS 服务器间的消息,只要这些消息是兼容 JMS 1.1 的。源和目的 JMS 资源通过 JNDI 查找,用于 JNDI 查找的客户类必须捆绑在模块里。然后在 JMS 桥配置里声明模块名。
过程 3.18. 创建 JMS 桥
这个过程演示了如何配置 JMS 桥从 JBoss EAP 5.x 移植消息到 JBoss EAP 6 服务器。
配置源 JBoss EAP 5.x 服务器上的 JMS 桥
为了避免版本间类的冲突,您必须使用下列过程配置 JBoss EAP 5.x 上的 JMS 桥。SAR 目录和桥的名称可以是任意的,也可以进行修改。- 在 JBoss EAP 5 的 deployment 目录里创建一个子目录来包含 SAR,如
EAP5_HOME/server/PROFILE_NAME/deploy/myBridge.sar
。 - 在
EAP5_HOME/server/PROFILE_NAME/deploy/myBridge.sar/
里创建一个名为META-INF
的子目录。 - 在
EAP5_HOME/server/PROFILE_NAME/deploy/myBridge.sar/META-INF/
目录里创建一个包含类似于下列信息的jboss-service.xml
文件。<server> <loader-repository> com.example:archive=unique-archive-name <loader-repository-config>java2ParentDelegation=false</loader-repository-config> </loader-repository> <!-- JBoss EAP 6 JMS Provider --> <mbean code="org.jboss.jms.jndi.JMSProviderLoader" name="jboss.messaging:service=JMSProviderLoader,name=EnterpriseApplicationPlatform6JMSProvider"> <attribute name="ProviderName">EnterpriseApplicationPlatform6JMSProvider</attribute> <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute> <attribute name="FactoryRef">jms/RemoteConnectionFactory</attribute> <attribute name="QueueFactoryRef">jms/RemoteConnectionFactory</attribute> <attribute name="TopicFactoryRef">jms/RemoteConnectionFactory</attribute> <attribute name="Properties"> java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory java.naming.provider.url=remote://EnterpriseApplicationPlatform6host:4447 java.naming.security.principal=jbossuser java.naming.security.credentials=jbosspass </attribute> </mbean> <mbean code="org.jboss.jms.server.bridge.BridgeService" name="jboss.jms:service=Bridge,name=MyBridgeName" xmbean-dd="xmdesc/Bridge-xmbean.xml"> <depends optional-attribute-name="SourceProviderLoader">jboss.messaging:service=JMSProviderLoader,name=JMSProvider</depends> <depends optional-attribute-name="TargetProviderLoader">jboss.messaging:service=JMSProviderLoader,name=EnterpriseApplicationPlatform6JMSProvider</depends> <attribute name="SourceDestinationLookup">/queue/A</attribute> <attribute name="TargetDestinationLookup">jms/queue/test</attribute> <attribute name="QualityOfServiceMode">1</attribute> <attribute name="MaxBatchSize">1</attribute> <attribute name="MaxBatchTime">-1</attribute> <attribute name="FailureRetryInterval">60000</attribute> <attribute name="MaxRetries">-1</attribute> <attribute name="AddMessageIDInHeader">false</attribute> <attribute name="TargetUsername">jbossuser</attribute> <attribute name="TargetPassword">jbosspass</attribute> </mbean> </server>
注意
使用load-repository
是为了确保 SAR 具有独立的类加载器。请注意,JNDI 查找和桥 "target" 都包括用户 "jbossuser"(密码 "jbosspass")的安全性凭证。这是因为 JBoss EAP 6 默认是设置了安全性的。用户 "jbossuser" 和密码 "jbosspass" 都是在具有guest
角色的ApplicationRealm
里使用EAP_HOME/bin/add_user.sh
脚本创建的。 - 将下列 JAR 从
EAP_HOME/modules/system/layers/base/
目录复制到EAP5_HOME/server/PROFILE_NAME/deploy/myBridge.sar/
目录。用实际的版本号替换每个 VERSION_NUMBER。org/hornetq/main/hornetq-core-VERSION_NUMBER.jar
org/hornetq/main/hornetq-jms-VERSION_NUMBER.jar
org/jboss/ejb-client/main/jboss-ejb-client-VERSION_NUMBER.jar
org/jboss/logging/main/jboss-logging-VERSION_NUMBER.jar
org/jboss/logmanager/main/jboss-logmanager-VERSION_NUMBER.jar
org/jboss/marshalling/main/jboss-marshalling-VERSION_NUMBER.jar
org/jboss/marshalling/river/main/jboss-marshalling-river-VERSION_NUMBER.jar
org/jboss/remote-naming/main/jboss-remote-naming-VERSION_NUMBER.jar
org/jboss/remoting3/main/jboss-remoting-VERSION_NUMBER.jar
org/jboss/sasl/main/jboss-sasl-VERSION_NUMBER.jar
org/jboss/netty/main/netty-VERSION_NUMBER.jar
org/jboss/remoting3/remote-jmx/main/remoting-jmx-VERSION_NUMBER.jar
org/jboss/xnio/main/xnio-api-VERSION_NUMBER.jar
org/jboss/xnio/nio/main.xnio-nio-VERSION_NUMBER.jar
注意
请不要简单地复制EAP_HOME/bin/client/jboss-client.jar
,因为 javax API 类会和 JBoss EAP 5.x 里的类相冲突。
配置目的 JBoss EAP 6 服务器上的 JMS 桥
在 JBoss EAP 6.1 以后的版本里,JMS 桥可以用于从任何兼容 JMS 1.1 的服务器上桥接消息。因为源和目标 JMS 资源是用 JNDI 进行查找的,源消息供应商或消息中介的 JNDI 查找类必须捆绑在 JBoss 模块里。下面的过程使用了虚拟的 'MyCustomMQ' 消息中介作为例子。- 为消息供应商创建 JBoss 模块。
- 在
EAP_HOME/modules/system/layers/base/
下为新的模块创建一个目录结构。main/
子目录将包含客户 JAR 和module.xml
文件。下面是为消息供应商 MyCustomMQ 创建的一个目录结构示例:EAP_HOME/modules/system/layers/base/org/mycustommq/main/
。 - 在
main/
子目录里,创建一个包含消息供应商的模块定义的module.xml
文件。下面是为消息供应商 MyCustomMQ 创建的module.xml
示例。<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.1" name="org.mycustommq"> <properties> <property name="jboss.api" value="private"/> </properties> <resources> <!-- Insert resources required to connect to the source or target --> <resource-root path="mycustommq-1.2.3.jar" /> <resource-root path="mylogapi-0.0.1.jar" /> </resources> <dependencies> <!-- Add the dependencies required by JMS Bridge code --> <module name="javax.api" /> <module name="javax.jms.api" /> <module name="javax.transaction.api"/> <!-- Add a dependency on the org.hornetq module since we send --> <!-- messages tothe HornetQ server embedded in the local EAP instance --> <module name="org.hornetq" /> </dependencies> </module>
- 从源资源复制消息供应商用于 JNDI 查找的的 JAR 到模块的
main/
子目录。MyCustomMQ 模块的目录结构应该类似于:modules/ `-- system `-- layers `-- base `-- org `-- mycustommq `-- main |-- mycustommq-1.2.3.jar |-- mylogapi-0.0.1.jar |-- module.xml
- 配置部署到 JBoss EAP 6 服务器的
messaging
子系统的 JMS 桥。- 在开始之前,请先停止服务器并备份当前的服务器配置文件。如果是作为独立服务器运行,它是
EAP_HOME/standalone/configuration/standalone-full-ha.xml
。如果是运行的受管域,请备份EAP_HOME/domain/configuration/domain.xml
以及EAP_HOME/domain/configuration/host.xml
。 - 在服务器配置文件里的
messaging
子系统里添加jms-bridge
元素。source
和target
元素提供的用于 JNDI 查找的 JMS 资源的名称。如果指定了user
和password
凭证,当创建 JMS 连接时它们会作为参数传入。下面是一个为消息供应商 MyCustomMQ 配置的jms-bridge
元素例子:<subsystem xmlns="urn:jboss:domain:messaging:1.3"> ... <jms-bridge name="myBridge" module="org.mycustommq"> <source> <connection-factory name="ConnectionFactory"/> <destination name="sourceQ"/> <user>user1</user> <password>pwd1</password> <context> <property key="java.naming.factory.initial" value="org.mycustommq.jndi.MyCustomMQInitialContextFactory"/> <property key="java.naming.provider.url" value="tcp://127.0.0.1:9292"/> </context> </source> <target> <connection-factory name="java:/ConnectionFactory"/> <destination name="/jms/targetQ"/> </target> <quality-of-service>DUPLICATES_OK</quality-of-service> <failure-retry-interval>500</failure-retry-interval> <max-retries>1</max-retries> <max-batch-size>500</max-batch-size> <max-batch-time>500</max-batch-time> <add-messageID-in-header>true</add-messageID-in-header> </jms-bridge> </subsystem>
在上面的例子里,JNDI 属性是在source
的context
元素里定义的。如上面的target
例子,如果忽略了context
元素,JMS 资源将在本地实例里进行查找。