当前位置: 首页 > ActiveMQ in Action 读书笔记 > 正文

8.2 ActiveMQ 与Apache Tomcat集成

8.2 Integrating with Apache Tomcat

Apache Tomcat is arguably the most widely used Java web container available today.Tomcat is used for both development and production throughout the world becauseit’s extremely robust, highly configurable, and commercially supported by a numberof companies. Because of its widespread use, Tomcat provides facilities for integratingthird-party resources such as JDBC data sources, JMS connection factories, and so on,and making them JNDI accessible. In this section, we’ll show you how to integrateActiveMQ with Apache Tomcat. You’ll need to download Apache Tomcat 6.0.26(http://mng.bz/75qc) and expand it on your computer.

8.2 与Apache Tomcat集成

Apache Tomcat毫无疑问是当今世界上使用做广泛的Java web容器.  Tomcat同时广泛用于 世界范围内的开发和生产环境的原因是其极其健壮,高可配置并受到很多公司的商业支持.因为应用广泛,Tomcat提供了多种工具用于集成诸如JDBC数据源,JMS连接工厂等第三方资源,并且可以通过JNDI访问这些第三方资源.本节中,我们将展示如何集成ActiveMQ到Apache Tomcat中.你需要下载Apache Tomcat 6.0.26(http://mng.bz/75qc)并解压到你的电脑中.

Tomcat offers two styles of configuration for JNDI resources: local JNDI context andglobal JNDI context. Configuring a local JNDI resource means that the resource is onlyavailable to a particular web application deployed to Tomcat. Configuring a resourcein the global JNDI context means that the resource is available to any web applicationdeployed to Tomcat. The configuration for each type of JNDI style is different, so let’sreview both.

Tomcat提供配置两种方式的JNDI:本地JNDI和全局JNDI.配置本地JNDI表示该JNDI资源只能被部署到Tomcat的特定的web程序使用,配置全局JNDI表示该JNDI资源可以被所有部署在Tomcat中的资源使用. 不同类型的JNDI的配置是不同的,下面让我们分别来看看这两种配置.

NOTE The sample applications for the local JNDI configuration and theglobal JNDI configuration can’t be deployed at the same time. This will causeclassloader issues and will prevent ActiveMQ from being deployed correctly.Make sure to only deploy one of the sample applications at a time. 

注意,使用了本地JNDI配置和全局JNDI配置的例子不能同时部署,否则会导致类加载问题,使得ActiveMQ不能正常部署.切记一次只能部署一种风格的JNDI.

8.2.1 Using local JNDI to integrate ActiveMQ with Tomcat

The local JNDI configuration restricts the availability of resources to the applicationwhere they’re defined. With this style of configuration for Tomcat, the JNDI resourcesare defined in a file named META-INF/context.xml. The following listing shows thecontext.xml file.
Listing 8.5 The Tomcat context.xml file

8.2.1 使用本地JNDI将ActiveMQ集成到Tomcat中

本地JNDI资源只能在定义它们的应用程序中使用.对于Tomcat来书,这种类型的JNDI资源在META-INF/context.xml文件中定义.下面的代码清单是context.xml文件内容.
代码清单8.5 Tomcat 的context.xml文件

<Context reloadable="true">
<Resource 
auth="Container"
name="jms/ConnectionFactory"
type="org.apache.activemq.ActiveMQConnectionFactory"
description="JMS Connection Factory"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
brokerURL="vm://localhost
brokerConfig=xbean:activemq.xml"
brokerName="MyActiveMQBroker"
/>
 
<Resource 
auth="Container"
name="jms/FooQueue"
type="org.apache.activemq.command.ActiveMQQueue"
description="JMS queue"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
physicalName="FOO.QUEUE"
/>
</Context>

Listing 8.5 is specific to Tomcat. The first element is named jms/Connection-Factory—it defines an ActiveMQ connection factory and takes advantage of featuresin ActiveMQ to start an instance of the broker via the connection factory. The secondelement named jms/FooQueue defines a JMS queue in ActiveMQ. This configurationfile lives with the web application and is automatically picked up by Tomcat to configurethe resources. Tomcat makes them available via a standard JNDI lookup to thesample web application.

代码清单8.5 是用于Tomcat的配置.第一个name属性为jms/Connection-Factory的资源定义了一个ActiveMQ连接工厂使用ActiveMQ的功能通过这个连接公工来启动一个代理实例.第二个name属性为jms/FooQueue的资源定义了一个ActiveMQ中使用的JMS消息队列.这个配置文件只在web程序中有效,并且Tomcat可以自动使用这个文件配置资源.Tomcat中的web程序可以使用JNDI lookup来访问并使用这些资源.

NOTE The $TOMCAT_HOME variable is being used to generically reference theTomcat installation directory. This isn’t something that you must set in yourenvironment.

注意:$TOMCAT_HOME变量表示Tomcat的安装目录,并不是必须要在你的环境中设置这个环境变量.(译注,window中需要设置这个环境变量)

To test the local JNDI resources, use the following steps:
Step 1 Copy the jms-webapp-local/target/jms-webapp.war file to the $TOMCAT_HOME/ webapps directory.
Step 2 Start up Tomcat:

按照下面的步骤来测试本地JNDI资源:
步骤1 拷贝jms-webapp-local/target/jms-webapp.war到$TOMCAT_HOME/ webapps目录下
步骤2 启动Tomcat

$ cd $TOMCAT_HOME
$ ./bin/catalina.sh run
 
Using CATALINA_BASE: /opt/apache-tomcat-6.0.26
Using CATALINA_HOME: /opt/apache-tomcat-6.0.26
Using CATALINA_TMPDIR: /opt/apache-tomcat-6.0.26/temp
Using JRE_HOME:System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
Using CLASSPATH: /opt/apache-tomcat-6.0.26/bin/bootstrap.jar
...
INFO - BrokerService - ActiveMQ 5.4.1 JMS Message Broker (FooBroker) is starting
...
Apr 8, 2010 9:03:03 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 3542 ms

You can see in the output that ActiveMQ is actually using the activemq.xml configurationfile because the brokerName FooBroker is being used. Passing the run argument tothe catalina.sh script will cause Tomcat to start up so that its output will appear in theterminal. The ability to see the output is helpful as noted earlier, and will also help youto verify the message receipt in a few steps.

你将看到,在输出信息中ActiveMQ实际上使用了activemq.xml配置文件,因为使用了FooBroker作为代理的名称.将”run”作为参数传递给catalina.sh脚本会启动Tomcat并且会在终端窗口中显示输出信息. 如前文提到的,能够看到输出信息很有用,这样可以帮助你检查在前面步骤中的输出信息.

As noted at the beginning of the chapter, this configuration takes advantage  ofa unique  feature in  ActiveMQ. This  feature allows  an ActiveMQ  broker to  bestarted simply by creating a connection factory and passing it a broker URI. Theconnection  factory attempts  to connect  to a  broker at  the URI,  and if  onedoesn’t exist, it’ll start one up. As you can see, this is a handy feature  inActiveMQ.

本章开头部分已经提到,这种配置方式充分利用了ActiveMQ的一个独特的功能,这个功能允许通过创建一个连接工厂并传递一个代理的URI给这个工厂来启动一个代理.因为连接工厂会尝试连接通过URI制定的代理,假如这个代理不存在连接工厂会尝试启动一个代理.就像你已经看到这,ActiveMQ的这个功能非常方便.

Step 3  Visit http://localhost:8080/jms-webapp  and use  the web  page to  send amessage. See figure 8.4 for an example of what you should see. 
Step 4  To  verify  the message   send, check   the terminal   to see   that theconsumer received  the message. See the following output:

Note the output from the terminal—specifically, the final line that’s a log messagefrom the JmsMessageDelegate bean. This line indicates that the message has beenconsumed, and you see the message payload is being output.

步骤3 访问http://localhost:8080/jms-webapp,通过这个web页发送一个示例消息,如图8.4所示.
步骤4 查看终端窗口以便检查消息的发送情况.和消息消费者接收消息.请看下面的额输出信息:

注意这里的来自控制台终端窗体的输出信息,最后一行应该是一个来自JmsMessageDelegate输出的长消息.这行输出表示消息已经被接收和处理过过了,因而你能看到payload消息被打印出来.

The local configuration of the ActiveMQ resources is a great approach because theseresources are contained with the web application. Nothing in Tomcat itself needs tobe changed or configured, which is different from the way that resources are configuredfor global JNDI.

配置本地ActiveMQ资源是一个非常好的方式因为这些资源都包含在应用程序中了.Tomcat本身不需要任何修改或者配置,这与配置全局JNDI资源不同.

8.2.2 Using global JNDI to integrate ActiveMQ with Tomcat

The global JNDI configuration in Tomcat is also easy to use. It just requires a bit ofadditional configuration and copying some JARs into the Tomcat lib directory. Theadvantage of global JNDI is that the resources are available to any web applicationsthat are deployed to Tomcat. In this style of configuration, the JNDI resources aredefined in configuration files that live with the Tomcat application server namedconf/server.xml and conf/context.xml. The following listing shows the relevant portionof the server.xml file.
Listing 8.6 The Tomcat server.xml file

8.2.2 使用全局JNDI将ActiveMQ集成到Tomcat中

Tomcat 中配置全局JNDI也很容易,因为全局配置仅仅需要一些额外的配置并拷贝一些Jar包到 Tomcat的lib目录中.使用全局JNDI的好处是这些资源可以被所有部署在Tomcat中的程序使用.这种方式配置时,JNDI资源是在Tomcat的conf/server.xml和conf/context.xml文件中定义的.下面的代码清单是server.xml 文件中相关的配置部分.
代码清单8.6 Tomcat的server.xml文件

<GlobalNamingResources>
...
<Resource 
auth="Container"
name="jms/ConnectionFactory"
type="org.apache.activemq.ActiveMQConnectionFactory"
description="JMS Connection Factory"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
brokerURL="vm://localhost?brokerConfig=xbean:conf/activemq.xml"
brokerName="MyActiveMQBroker"
/>
 
<Resource 
auth="Container"
name="jms/FooQueue"
type="org.apache.activemq.command.ActiveMQQueue"
description="A sample queue"
factory="org.apache.activemq.jndi.JNDIReferenceFactory"
physicalName="FOO.QUEUE"
/>
...
</GlobalNamingResources>

The <Resource> elements in the server.xml file shown in listing 8.6 register theJNDIReferenceFactory object with Tomcat for creating the noted object types—theActiveMQConnectionFactory and  the ActiveMQQueue.  Again, ActiveMQ  is unique inthe  fact  that  a  full  broker   instance  can  be  created  by  creating   anActiveMQConnectionFactory.

代码清单8.6中 Tomcat使用server.xml 文件的 <Resource>元素注册了JNDIReferenceFactory对象用来创建ActiveMQConnectionFactory和ActiveMQQueue.同样,ActiveMQ的独特之处是可以通过创建一个ActiveMQConnectionFactory来创建一个完整的代理实例.

The brokerURL attribute is used to pass the broker URI, which allows any of  thesupported transports (TCP, VM,  and so forth) to  be used. It also  supports theoptional brokerConfig parameter  used to point  to a configuration  file for theActiveMQ instance that’s being started.

The next file to be changed is the context.xml file; the relevant additions are shown next.

Listing 8.7 The Tomcat context.xml file

brokerURL属性用来传递代理的RUI,该URI允许使用任何支持的传输连接协议(TCP, VM, 等),并且也支持使用可选的代理配置参数,该参数指向一个ActiveMQ实例启动时使用的配置文件.

另一个需要被修改的文件是context.xml文件,下面是该文件中与配置有关的部分:

代码清单8.7 Tomcat 的 context.xml配置文件

<Context>
...
<ResourceLink 
global="jms/ConnectionFactory"
name="jms/ConnectionFactory"
/>
 
<ResourceLink 
global="jms/FooQueue"
name="jms/FooQueue"
/>
...
</Context>

The <ResourceLink> elements define a link to the resources that are defined in theglobal JNDI context and expose these resources to all web applications deployed inthis instance of Tomcat.

To test the global JNDI resource configurations, use the following steps:
Step 1 Copy the following JARs into the $TOMCAT_HOME/lib directory:

<ResourceLink>元素定义了一个指向了全局JNDI中定义的资源的链接,同时将这些资源暴露给已部署在Tomcat中的web程序.

按照下面的步骤测试全局JNDI资源配置:
步骤1 拷贝下面的jar包到$TOMCAT_HOME/lib 目录

 activemq-all-5.4.1.jar 
 spring-beans-2.5.6.jar
 aopalliance-1.0.jar 
 spring-context-2.5.6.jar
 commons-logging-1.1.1.jar 
 spring-context-support-2.5.6.jar
 geronimo-j2ee-management_1.0_spec-1.0.jar 
 spring-core-2.5.6.jar
 geronimo-jms_1.1_spec-1.1.1.jar 
 spring-jms-2.5.6.jar
 geronimo-jta_1.0.1B_spec-1.1.1.jar 
 spring-tx-2.5.6.jar
 log4j-1.2.14.jar 
 spring-web-2.5.6.jar
 org.osgi.core-4.1.0.jar 
 spring-webmvc-2.5.6.jar
 spring-aop-2.5.6.jar

The easiest place to get these JARs is from the jms-webapp-local project that was usedfor the local JNDI configuration after that project is built. After running the Mavencommand to build the jms-webapp-local project, take a look in the jms-webapplocal/target/jms-webapp/WEB-INF/lib/ directory for these JARs. Simply copy the JARsfrom that directory into the $TOMCAT_HOME/lib directory.

获取这些jar包的简易方法是使用配置本地JNDI资源的编译后的jms-webapp-local工程中的jar包.运行Maven命令编译完 jms-webapp-local工程后,到jms-webapplocal/target/jms-webapp/WEB-INF/lib/ 目录下可获取这些jar包,然后拷贝这些jar包到$TOMCAT_HOME/lib目录下.

Step 2 After making changes to the configuration files as noted, they must beincluded in the WAR file. To build the jms-webapp-global project and createa new WAR file, from the command line, run the following Maven command:

步骤2 修改好前面提道德配置文件后,这些修改必须被包含到war文件中,可以在命令行中运行下面的Maven命令构造 jms-webapp-global工厂并创建一个新的war文件:

$ cd jms-webapp-global
$ mvn clean install
...
[INFO] Scanning for projects...
[INFO] --------------------------------------------------------------------
[INFO] Building jms-webapp-global
[INFO] task-segment: [clean, install]
[INFO] --------------------------------------------------------------------
...
[INFO] --------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] --------------------------------------------------------------------
...

After running this command, a WAR file will exist in the target directory.

Step 3 Copy the jms-webapp-global/activemq.xml file to $TOMCAT_HOME/conf/activemq.xml. This makes the ActiveMQ configuration file available on theclasspath.

执行完上面的命令后,target目录下会生成一个war文件.

步骤3 拷贝 jms-webapp-global/activemq.xml文件到$TOMCAT_HOME/conf/activemq.xml.这是的ActiveMQ的配置文件可以在classpath中找到.(译注: 貌似这样不行,报异常找不到这个文件,需要在lib下面见一个conf文件夹,将activemq.xml拷贝过来才行)

Step 4 Copy the jms-webapp-global/target/jms-webapp.war to the $TOMCAT_HOME/webapps directory. This deploys the example web application.

Step 5 Start up Tomcat using the following command:

步骤4 拷贝 jms-webapp-global/target/jms-webapp.war 文件到$TOMCAT_HOME/webapps目录下.这样就完成了该程序的部署.

步骤5  使用下面的命令启动Tomcat

$ cd $TOMCAT_HOME
$ ./bin/catalina.sh run
 
Using CATALINA_BASE: /opt/apache-tomcat-6.0.26
Using CATALINA_HOME: /opt/apache-tomcat-6.0.26
Using CATALINA_TMPDIR: /opt/apache-tomcat-6.0.26/temp
Using JRE_HOME:/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
Using CLASSPATH:/opt/apache-tomcat-6.0.26/bin/bootstrap.jar
...
INFO - BrokerService - ActiveMQ 5.4.1 JMS MessageBroker (FooBroker) is starting
...
Apr 9, 2010 8:54:59 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 3365 ms

Again, you can see that ActiveMQ is using the activemq.xml configuration file based on the output stating that the FooBroker is starting.

通过控制台的输出信息你会再次看到, ActiveMQ 正在使用配置文件activemq.xml, 并且FooBroker已经启动了.

Step 6 Visit http://localhost:8080/jms-webapp and send a message.

步骤6 访问http://localhost:8080/jms-webapp 并发送一个消息

Step 7 To confirm a successful message send, check the terminal for the following output:

步骤7 为确定消息已发送成功,检查命令行终端的输出信息:

...
INFO: Server startup in 3365 ms
INFO - SingleConnectionFactory - Established shared
JMS Connection:ActiveMQConnection {id=ID:mongoose.local-49429-1270868098091-2:1,clientId=null,started=false}
INFO - JmsMessageDelegate - Consumed message with payload:This is a test message

In the output shown, note that the last line of output from the JmsMessageDelegatebean shows the message payload that was consumed by the JmsMessageDelegatebean.

上面的输出系想你中,需要注意到额是最后一行输出是来自JmsMessageDelegate的,显示的是被JmsMessageDelegate接收并处理过的payload消息.

For some projects, configuring ActiveMQ to use the Tomcat global JNDI context isappropriate because there may be multiple projects that need access to thoseresources. In some situations, it makes sense to control ActiveMQ from within theTomcat process. The disadvantage is that Tomcat and ActiveMQ are now contendingfor the same resources inside of the same JVM. For some projects, this isn’t a problem,and is therefore an acceptable trade-off.

对一些工程来说,使用Tomcat的全局JNDI配置ActiveMQ是合适的.因为可能有多个工成需要访问这些全局资源.有些情况下,在Tomcat内部控制ActiveMQ比较合理.这种方式配置的一个不足是Tomcat和ActiveMQ在同一个JVM中争用资源.对于一些工程来说这种争用也许不是问题,因而这种方式也成为一种折中方案.

But Tomcat isn’t the only viable open source web container. Jetty is a formidable alternative.

然而Tomcat并不是唯一的开源的web容器, Jetty就是一个强大的对手.

赞 赏

   微信赞赏  支付宝赞赏


本文固定链接: https://www.jack-yin.com/coding/translation/activemq-in-action/1585.html | 边城网事

该日志由 边城网事 于2013年11月19日发表在 ActiveMQ in Action 读书笔记 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: 8.2 ActiveMQ 与Apache Tomcat集成 | 边城网事

8.2 ActiveMQ 与Apache Tomcat集成 暂无评论

发表评论

快捷键:Ctrl+Enter