阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

JBoss WildFly 7 连接到 ActiveMQ 5.9

108次阅读
没有评论

共计 9541 个字符,预计需要花费 24 分钟才能阅读完成。

我们最近发现大量的客户都有一个同样的问题:在运行于 JBoss Wildfly 7 中的 HornetQ JMS 实现和独立运行的 ActiveMQ 服务器之间,如何才能建立一个桥接。ActiveMQ 作为一个独立运行的消息代理(message broker),一直是一个可靠的选择。而且随着 Red Hat 已经收购了 Fusesource(译者注:Fusesource 是 ActiveMQ 项目的维护组织,Red Hat 此前在 2006 年收购了 JBoss,现在 JBoss 和 Fusesource 都是 Red Hat 旗下的开源组织),在等待 JBoss AMQ 版本的 ActiveMQ 推出期间(译者注:JBoss 基于 ActiveMQ 定制了一个新 MQ,官方名称为 JBoss A-MQ),这个问题尤其突出。

不使用桥接当然也是可能的,直接可以把 ActiveMQ 引入到 JBoss,然后使用 ActiveMQ 上暴露的 JMS 队列。但是这个方式的缺点在于,如果 ActiveMQ 服务器由于某些原因停止工作的话,运行于 JBoss 中的 JMS 生产者将会失败,消费者也将会断开连接并且需要重连(译者注:原文拼写错误,误将 reconnect 拼写为 reconnet)。一个更好的架构是,JBoss 中的生产者先入列到一个本地 HornetQ 队列,然后将这些消息桥接到外部的 ActiveMQ 代理。在这个架构中,生产者可以在 ActiveMQ 宕机期间持续地入列消息,等到 ActiveMQ 再次工作时这些消息将会从 HornetQ 传输到 ActiveMQ。

Linux 系统下 ActiveMQ 安装 http://www.linuxidc.com/Linux/2012-03/55623.htm

Ubuntu 下的 ACTIVEMQ 服务器 http://www.linuxidc.com/Linux/2008-07/14587.htm

Spring+JMS+ActiveMQ+Tomcat 实现消息服务 http://www.linuxidc.com/Linux/2011-10/44632.htm

Linux 环境下面 ActiveMQ 端口号设置和 WEB 端口号设置 http://www.linuxidc.com/Linux/2012-01/51100.htm

配置桥接的过程是相当简单的, 我们需要做以下的事情: 

1.   下载 ActiveMQ 资源适配器归档文件
2.   在 WildFly 7 中安装和配置资源适配器
3.   在 WildFly 7 内嵌的 HornetQ 实例中, 创建一个本地 JMS 队列
4.   在本地队列和远程 ActiveMQ 队列之间, 创建一个 JMS 桥接.

为了开始, 我下载了 ActiveMQ 资源适配器, 从这个页面:http://repo1.maven.org/maven2/org/apache/activemq/activemq-rar/
 
下一步, 我们需要使用如下的命令, 为 activemq 资源适配器, 创建一个 JBoss 模块,:

mkdir modules/system/layers/base/org/activemq/main
cd modules/system/layers/base/org/activemq/main
unzip ~/activemq-rar-5.9.0.rar

这将会创建一个包含模块层次结构的目录, 并将 activemq 资源适配器文件解压到此目录.JBoss 只支持把拓展的资源适配器作为模块, 所以我们解压归档文件的内容. 同时, 我们需要在 activemq/main 目录, 创建一个包含如下内容的 module.xml 文件. 这是为了让 JBoss 区分, 哪些 jar 文件需要加装, 哪些类不需要和其它模块共享(我们不希望和任何库的实现相冲突).

<module xmlns=”urn:jboss:module:1.1″ name=”org.apache.activemq” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”>
  <resources>
    <resource-root path=”.”/>
    <resource-root path=”activemq-broker-5.9.0.jar”/>
    <resource-root path=”activemq-client-5.9.0.jar”/>
    <resource-root path=”activemq-jms-pool-5.9.0.jar”/>
    <resource-root path=”activemq-kahadb-store-5.9.0.jar”/>
    <resource-root path=”activemq-openwire-legacy-5.9.0.jar”/>
    <resource-root path=”activemq-pool-5.9.0.jar”/>
    <resource-root path=”activemq-protobuf-1.1.jar”/>
    <resource-root path=”activemq-ra-5.9.0.jar”/>
    <resource-root path=”activemq-spring-5.9.0.jar”/>
    <resource-root path=”aopalliance-1.0.jar”/>
    <resource-root path=”commons-pool-1.6.jar”/>
    <resource-root path=”commons-logging-1.1.3.jar”/>
    <resource-root path=”hawtbuf-1.9.jar”/>
    <resource-root path=”spring-aop-3.2.4.RELEASE.jar”/>
    <resource-root path=”spring-beans-3.2.4.RELEASE.jar”/>
    <resource-root path=”spring-context-3.2.4.RELEASE.jar”/>
    <resource-root path=”spring-core-3.2.4.RELEASE.jar”/>
    <resource-root path=”spring-expression-3.2.4.RELEASE.jar”/>
    <resource-root path=”xbean-spring-3.14.jar”/>
  </resources>
  <exports>
    <exclude path=”org/springframework/**”/>
    <exclude path=”org/apache/xbean/**”/>
    <exclude path=”org/apache/commons/**”/>
    <exclude path=”org/aopalliance/**”/>
    <exclude path=”org/fusesource/**”/>
  </exports>
  <dependencies>
    <module name=”Javax.api”/>
    <module name=”org.slf4j”/>
    <module name=”javax.resource.api”/>
    <module name=”javax.jms.api”/>
    <module name=”javax.management.j2ee.api”/>
  </dependencies>
</module>

要对模块进行配置我们需要编辑 JBoss 的配置文件,这里我从 standalone-full.xml 开始,因为它已经对 HornetQ 进行了配置(这节省了我们很多时间)。我们需要添加 activeMQ 资源适配器,把下面这一行

<subsystem
  xmlns=”urn:jboss:domain:resource-adapters:1.0″/>

改成

<subsystem xmlns=”urn:jboss:domain:resource-adapters:1.1″>
    <resource-adapters>
        <resource-adapter id=”activemq-rar.rar”>
            <module slot=”main” id=” org.apache.activemq “/>
            <transaction-support>NoTransaction</transaction-support>
            <config-property name=”ServerUrl”>
                tcp://localhost:61616
            </config-property>
            <connection-definitions>
                <connection-definition class-name=”org.apache.activemq.ra.ActiveMQManagedConnectionFactory” jndi-name=” java:/AMQConnectionFactory ” enabled=”true” use-java-context=”true” pool-name=”AMQConnectionFactory”/>
            </connection-definitions>
            <admin-objects>
                <admin-object class-name=”org.apache.activemq.command.ActiveMQQueue” jndi-name=” queue/JMSBridgeTargetQ ” use-java-context=”true” pool-name=”target_queue”>
                    <config-property name=”PhysicalName”>
                        JMSBridgeTargetQ
                    </config-property>
                </admin-object>
            </admin-objects>
        </resource-adapter>
    </resource-adapters>
</subsystem>

这样就创建了一个资源适配器,它使用了我们刚才创建的 org.apache.activemq 模块,并连接到了运行在 tcp://localhost:61616 上的远程 ActiveMQ 服务器上。它注册了一个连接工厂,名叫 java:AMQConnectionFactory 使得我们可以连到远程服务器上,也创建了一个名为queue/JMSBridgeTargetQ 的本地 JNDI,该 JNDI 将被绑定到名为 JMSBridgeTargetQ 的 ActiveMQ 队列上。

下一步就是配置桥接器和本地队列。我们来编辑 hornetq 子系统,在 hornetQ 服务器的定义后面,添加一个 JMS 桥接器。

<jms-bridge name=”simple-jms-bridge”>
    <source>
        <connection-factory name=” ConnectionFactory “/>
        <destination name=” queue/JMSBridgeSourceQ “/>
    </source>
    <target>
        <connection-factory name=” AMQConnectionFactory “/>
        <destination name=” queue/JMSBridgeTargetQ “/>
    </target>
    <quality-of-service>AT_MOST_ONCE</quality-of-service>
    <failure-retry-interval>1000</failure-retry-interval>
    <max-retries>-1</max-retries>
    <max-batch-size>10</max-batch-size>
    <max-batch-time>100</max-batch-time>
</jms-bridge> .

这样就创建了一个桥接器,它使用名为 ConnectionFactory 的连接工厂来消耗本地队列里的消息,该队列对应的 JNDI 名字是queue/JMSBridgeSourceQ。随后它将使用一个名为AMQConnectionFactory 的连接工厂 (它由我们的资源适配器创建) 来把消息发送到 JNDI 名称为 queue/JMSBridgeTargetQ 的本地队列中。我们的资源适配器会把这映射到远程 ActiveMQ 队列中。我们也需要在该配置文件的 jms-destinations 部分里,创建一个名为JMSBridgeSourceQ 的本地队列。

<jms-destinations>
    <jms-queue name=”JMSBridgeSourceQueue”>
        <entry name=” java:/queue/JMSBridgeSourceQ “/>
        <entry name=”java:jboss/exported/jms/queue/JMSBridgeSourceQ “/>
        <durable>true</durable>
    </jms-queue>
</jms-destinations>

这个队列有两个 JNDI 名称,使得它可以同时从内部 (被桥接器) 和外部 (被客户端) 访问到.

为了在 ActiveMQ 创建一个通信目的地, 我们通过 bin/activemq 开始命令启动 ActiveMQ, 并使用 ActiveMQ hawtio 控制台(http://localhost:8161/hawtio), 通过浏览 ActiveMQ -> Broker ->  Localhost -> Queue 并选择 Create 来创建一个新的 JMS 队列. 在这个例子中设置队列名为JMSBridgeTargetQ.

JBoss WildFly 7 连接到 ActiveMQ 5.9

这就是所有必需的配置文件. 我们应该可以启动 WildFly 服务, 看到桥接开始工作并连接到 ActiveMQ.

 13:43:11,959 INFO  [org.jboss.as.remoting] (MSC service thread 1-2) JBAS017100: Listening on 127.0.0.1:9999
13:43:12,447 INFO  [org.jboss.as.remoting] (MSC service thread 1-2) JBAS017100: Listening on 127.0.0.1:4447
13:43:12,452 INFO  [org.jboss.as.connector.deployers.RaXmlDeployer] (MSC service thread 1-2) IJ020001: Required license terms for file:/home/matt/jboss-as-7.2.0.Final/modules/system/layers/base/org/apache/activemq/main/./
13:43:12,511 INFO  [org.jboss.as.connector.deployment] (MSC service thread 1-2) JBAS010406: Registered connection factory java:/AMQConnectionFactory
13:43:12,522 INFO  [org.jboss.as.connector.deployment] (MSC service thread 1-2) JBAS010405: Registered admin object at java:/queue/JMSBridgeTargetQ
13:43:12,538 INFO  [org.hornetq.core.server] (MSC service thread 1-1) HQ221024: Started Netty Acceptor version 3.6.2.Final-c0d783c 127.0.0.1:5455 for CORE protocol
13:43:12,550 INFO  [org.jboss.as.connector.deployers.RaXmlDeployer] (MSC service thread 1-2) IJ020002: Deployed: file:/home/matt/jboss-as-7.2.0.Final/modules/system/layers/base/org/apache/activemq/main/./
13:43:12,555 INFO  [org.hornetq.core.server] (MSC service thread 1-1) HQ221024: Started Netty Acceptor version 3.6.2.Final-c0d783c 127.0.0.1:5445 for CORE protocol
13:43:12,558 INFO  [org.hornetq.core.server] (MSC service thread 1-1) HQ221009: Server is now live
13:43:12,561 INFO  [org.hornetq.core.server] (MSC service thread 1-1) HQ221003: HornetQ Server version 2.3.0.CR1 (buzzzzz!, 122) [1ef84f49-88d8-11e3-a2ac-f9239574df9d]
13:43:12,584 INFO  [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-1) JBAS010400: Bound data source [java:jboss/datasources/ExampleDS]
13:43:12,600 INFO  [org.jboss.as.connector.deployment] (MSC service thread 1-1) JBAS010401: Bound JCA ConnectionFactory [java:/AMQConnectionFactory]
13:43:12,611 INFO  [org.jboss.as.connector.deployment] (MSC service thread 1-1) JBAS010401: Bound JCA AdminObject [java:/queue/JMSBridgeTargetQ]
13:43:12,683 INFO  [org.jboss.as.messaging] (ServerService Thread Pool — 58) JBAS011601: Bound messaging object to jndi name java:jboss/exported/jms/RemoteConnectionFactory
13:43:12,686 INFO  [org.hornetq.core.server] (ServerService Thread Pool — 60) HQ221005: trying to deploy queue jms.queue.JMSBridgeSourceQueue
13:43:12,733 INFO  [org.jboss.as.messaging] (ServerService Thread Pool — 60) JBAS011601: Bound messaging object to jndi name java:jboss/exported/jms/queue/JMSBridgeSourceQ
13:43:12,738 INFO  [org.jboss.as.messaging] (ServerService Thread Pool — 60) JBAS011601: Bound messaging object to jndi name java:/queue/JMSBridgeSourceQ
13:43:12,747 INFO  [org.jboss.as.messaging] (ServerService Thread Pool — 59) JBAS011601: Bound messaging object to jndi name java:/ConnectionFactory
13:43:12,916 INFO  [org.jboss.as.connector.deployment] (MSC service thread 1-2) JBAS010406: Registered connection factory java:/JmsXA
13:43:12,968 INFO  [org.hornetq.ra] (MSC service thread 1-2) HornetQ resource adaptor started
13:43:12,969 INFO  [org.jboss.as.connector.services.resourceadapters.ResourceAdapterActivatorService$ResourceAdapterActivator] (MSC service thread 1-2) IJ020002: Deployed: file://RaActivatorhornetq-ra
13:43:12,974 INFO  [org.jboss.as.connector.deployment] (MSC service thread 1-1) JBAS010401: Bound JCA ConnectionFactory [java:/JmsXA]
13:43:13,286 INFO  [org.jboss.messaging] (ServerService Thread Pool — 58) JBAS011610: Started JMS Bridge simple-jms-bridge
13:43:13,439 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015961: Http management interface listening on http://127.0.0.1:9990/management
13:43:13,440 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015951: Admin console listening on http://127.0.0.1:9990
13:43:13,440 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss AS 7.2.0.Final “Janus” started in 9912ms – Started 169 of 228 services (58 services are passive or on-demand)

我们现在可以在 JBoss 的 JMSBridgeSourceQ 里面放置消息, 它们最后将处于 ActiveMQ 的 JMSBridgeTargetQ 之中.

将桥接的消息流方向反过来也是可能的, 尽管消费者的桥接和生产者的桥接并非同样至关重要. 消费者的桥接, 通常更倾向于直接从映射的 JNDI 名字 (在 queue/JMSBridgeTargetQ 里面, 由资源适配器创建) 获取消息, 而不是将消息放置在本地队列后, 再从本地获取消息.

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-20发表,共计9541字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中