`
周英能
  • 浏览: 186002 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

spring jms

 
阅读更多

简介

  ActiveMQ 是开源的JMS实现,Geronimo应用服务器就是使用的ActiveMQ提供JMS服务。ActiveMQ5.0相比以前版本提供了一些非常有用的新功能:

  1. AMQ Message Store (Faster Persistence!)
  2. Cursors (To handle very large number of stored messages)
  3. Blob Messages
  4. Command Agent
  5. Enterprise Integration Patterns via Camel Integration
  6. Logging a warning if you forget to start a Connection
  7. Message Transformation
  8. Mirrored Queues
  9. Flow Control 

鉴于目前关于ActiveMQ5.0的文章比较少,故准备写一系列ActiveMQ的使用方面的文章。本篇先从安装开始。 

安装

  1. http://activemq.apache.org/download.html 下载5.0.0发行包,解压到需要安装ActiveMQ的文件夹,记为/path/to/activemq。
  2. unix环境activemq文件夹需要执行权限,执行如下命令  chmod -R 755 /path/to/activemq 

启动

  1. window环境运行/path/to/activemq/bin/activemq.bat
  2. unix环境运行/path/to/activemq/bin/activemq

测试

ActiveMQ默认使用的TCP连接端口是61616, 通过查看该端口的信息可以测试ActiveMQ是否成功启动

  1. window环境运行  netstat -an|find "61616"
  2. unix环境运行netstat -an|grep 61616

监控

ActiveMQ5.0版本默认启动时,启动了内置的jetty服务器,提供一个demo应用和用于监控ActiveMQ的admin应用。

admin:http://127.0.0.1:8161/admin/

demo:http://127.0.0.1:8161/demo/

 

点击demo应用中的“ Market data publisher ”,就会发一些测试的消息。转到admin页面的topics menu下面(queue和topic的区别见 http://andyao.iteye.com/blog/153173 ),可以看到消息在增长。

配置

ActiveMQ5.0的配置文件在/path/to/activemq/conf目录下面。主要配置文件为activemq.xml

简介

上一篇http://www.iteye.com/topic/15317介绍了ActiveMQ5.0的安装,这一篇将介绍的配置。ActiveMQ包含了很多features(详见http://activemq.apache.org/features.html ),   
不同的需求,不同的环境,需要不同的features,当然需要不同的配置。在这里我只写了最基本的配置,算是抛砖了,希望引出更多关于ActiveMQ的高级配置。
假设已经正确安装ActiveMQ5.0,同时及其IP地址为192.168.1.148,具体使用时可以改为自己的IP。下面讲解的配置实现的features如下:

  1. 客户端可以通过tcp://192.168.1.148连接ActiveMQ。
  2. 消息持久化保存,重启服务器不会丢失消息。
  3. 可以通过http://192.168.1.148:8161/admin监控ActiveMQ服务器

配置

ActiveMQ默认使用的是XML格式配置,从4.0版本开始用MBean的方式实现XML配置,配置文件在${activemq.home}/conf目录下,文件名为activemq.xml。最新的默认配置见
http://svn.apache.org/repos/asf/activemq/trunk/assembly/src/release/conf/activemq.xml 。下面为本篇文章使用的配置,及重要部分的解释。

 

Xml代码 复制代码
  1. <beans  
  2.   xmlns="http://www.springframework.org/schema/beans"  
  3.   xmlns:amq="http://activemq.org/config/1.0"  
  4.   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd   
  5.   http://activemq.org/config/1.0 http://activemq.apache.org/schema/activemq-core.xsd   
  6.   http://activemq.apache.org/camel/schema/spring>  
  7.     
  8.   <!-- persistent="true"表示要持久化存储消息,和子元素persistenceAdapter结合使用 -->  
  9.   <!-- dataDirectory默认的存储持久化数据的目录 -->  
  10.   <!-- brokerName 设置broker的name,在注意在网络上必须是唯一的-->  
  11.   <!-- 更多参考http://activemq.apache.org/xbean-xml-reference-50.html#XBeanXMLReference5.0-brokerelement -->  
  12.   <broker xmlns="http://activemq.org/config/1.0" brokerName="192.168.1.148" persistent ="true" dataDirectory="${activemq.base}/data" useShutdownHook="false">  
  13.     
  14.     <!-- Destination specific policies using destination names or wildcards -->  
  15.     <!-- wildcards意义见http://activemq.apache.org/wildcards.html -->  
  16.     <destinationPolicy>  
  17.       <policyMap>  
  18.         <policyEntries>  
  19.        <!-- 这里使用了wildcards,表示所有以EUCITA开头的topic -->  
  20.           <policyEntry topic="EUCITA.>" producerFlowControl="false" memoryLimit="10mb">  
  21.             <!-- 分发策略 -->  
  22.         <dispatchPolicy>  
  23.           <!-- 按顺序分发 -->  
  24.               <strictOrderDispatchPolicy/>  
  25.             </dispatchPolicy>  
  26.         <!--  恢复策略-->  
  27.             <subscriptionRecoveryPolicy>  
  28.           <!-- 只恢复最后一个message -->  
  29.               <lastImageSubscriptionRecoveryPolicy/>  
  30.             </subscriptionRecoveryPolicy>  
  31.           </policyEntry>  
  32.         </policyEntries>  
  33.       </policyMap>  
  34.     </destinationPolicy>  
  35.   
  36.     <!-- The transport connectors ActiveMQ will listen to -->  
  37.     <transportConnectors>  
  38.        <transportConnector name="openwire" uri="tcp://192.168.1.148:61616" discoveryUri="multicast://default"/>  
  39.        <transportConnector name="ssl"     uri="ssl://192.168.1.148:61617"/>  
  40.        <transportConnector name="stomp"   uri="stomp://192.168.1.148:61613"/>  
  41.        <transportConnector name="xmpp"    uri="xmpp://192.168.1.148:61222"/>  
  42.     </transportConnectors>  
  43.       
  44.     <!-- 消息持久化方式 -->  
  45.     <persistenceAdapter>  
  46.       <amqPersistenceAdapter directory="${activemq.base}/data"/>  
  47.     </persistenceAdapter>  
  48. </broker>  
  49.   
  50.   <!-- lets create a command agent to respond to message based admin commands on the ActiveMQ.Agent topic -->  
  51.     <commandAgent xmlns="http://activemq.org/config/1.0"/>  
  52.      
  53.   <!-- An embedded servlet engine for serving up the Admin console -->  
  54.   <jetty xmlns="http://mortbay.com/schemas/jetty/1.0">  
  55.     <connectors>  
  56.       <nioConnector port="8161" />  
  57.     </connectors>  
  58.   
  59.     <handlers>  
  60.       <webAppContext contextPath="/admin" resourceBase="${activemq.base}/webapps/admin" logUrlOnStart="true" />        
  61.       <webAppContext contextPath="/demo" resourceBase="${activemq.base}/webapps/demo" logUrlOnStart="true" />          
  62.     </handlers>  
  63.   </jetty>    
  64. </beans>  
Xml代码  收藏代码
  1. <beans  
  2.   xmlns="http://www.springframework.org/schema/beans"  
  3.   xmlns:amq="http://activemq.org/config/1.0"  
  4.   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
  5.   http://activemq.org/config/1.0 http://activemq.apache.org/schema/activemq-core.xsd  
  6.   http://activemq.apache.org/camel/schema/spring>  
  7.    
  8.   <!-- persistent="true"表示要持久化存储消息,和子元素persistenceAdapter结合使用 -->  
  9.   <!-- dataDirectory默认的存储持久化数据的目录 -->  
  10.   <!-- brokerName 设置broker的name,在注意在网络上必须是唯一的-->  
  11.   <!-- 更多参考http://activemq.apache.org/xbean-xml-reference-50.html#XBeanXMLReference5.0-brokerelement -->  
  12.   <broker xmlns="http://activemq.org/config/1.0" brokerName="192.168.1.148" persistent ="true" dataDirectory="${activemq.base}/data" useShutdownHook="false">  
  13.    
  14.     <!-- Destination specific policies using destination names or wildcards -->  
  15.     <!-- wildcards意义见http://activemq.apache.org/wildcards.html -->  
  16.     <destinationPolicy>  
  17.       <policyMap>  
  18.         <policyEntries>  
  19.        <!-- 这里使用了wildcards,表示所有以EUCITA开头的topic -->  
  20.           <policyEntry topic="EUCITA.>" producerFlowControl="false" memoryLimit="10mb">  
  21.             <!-- 分发策略 -->  
  22.         <dispatchPolicy>  
  23.           <!-- 按顺序分发 -->  
  24.               <strictOrderDispatchPolicy/>  
  25.             </dispatchPolicy>  
  26.         <!--  恢复策略-->  
  27.             <subscriptionRecoveryPolicy>  
  28.           <!-- 只恢复最后一个message -->  
  29.               <lastImageSubscriptionRecoveryPolicy/>  
  30.             </subscriptionRecoveryPolicy>  
  31.           </policyEntry>  
  32.         </policyEntries>  
  33.       </policyMap>  
  34.     </destinationPolicy>  
  35.   
  36.     <!-- The transport connectors ActiveMQ will listen to -->  
  37.     <transportConnectors>  
  38.        <transportConnector name="openwire" uri="tcp://192.168.1.148:61616" discoveryUri="multicast://default"/>  
  39.        <transportConnector name="ssl"     uri="ssl://192.168.1.148:61617"/>  
  40.        <transportConnector name="stomp"   uri="stomp://192.168.1.148:61613"/>  
  41.        <transportConnector name="xmpp"    uri="xmpp://192.168.1.148:61222"/>  
  42.     </transportConnectors>  
  43.      
  44.     <!-- 消息持久化方式 -->  
  45.     <persistenceAdapter>  
  46.       <amqPersistenceAdapter directory="${activemq.base}/data"/>  
  47.     </persistenceAdapter>  
  48. </broker>  
  49.   
  50.   <!-- lets create a command agent to respond to message based admin commands on the ActiveMQ.Agent topic -->  
  51.     <commandAgent xmlns="http://activemq.org/config/1.0"/>  
  52.     
  53.   <!-- An embedded servlet engine for serving up the Admin console -->  
  54.   <jetty xmlns="http://mortbay.com/schemas/jetty/1.0">  
  55.     <connectors>  
  56.       <nioConnector port="8161" />  
  57.     </connectors>  
  58.   
  59.     <handlers>  
  60.       <webAppContext contextPath="/admin" resourceBase="${activemq.base}/webapps/admin" logUrlOnStart="true" />       
  61.       <webAppContext contextPath="/demo" resourceBase="${activemq.base}/webapps/demo" logUrlOnStart="true" />         
  62.     </handlers>  
  63.   </jetty>   
  64. </beans>  

注释

关于XML配置中元素的具体信息可以参考http://activemq.apache.org/xbean-xml-reference-50.html 下面介绍本篇配置使用的一些重要元素。

DispathPolicy

ActiveMQ支持3中不同的分发策略(避免翻译了以后误解,这里用原文):

  1. <roundRobinDispatchPolicy>:Simple dispatch policy that sends a message to every subscription that matches the message.
  2. <simpleDispatchPolicy>:Simple dispatch policy that sends a message to every subscription that matches the message.
  3. <strictOrderDispatchPolicy>:Dispatch policy that causes every subscription to see messages in the same order.

SubscriptionRecoveryPolicy

ActiveMQ支持6种恢复策略,可以自行选择使用不同的策略

  1. <fixedCountSubscriptionRecoveryPolicy>: keep a fixed count of last messages.
  2. <fixedSizedSubscriptionRecoveryPolicy>: keep a fixed amount of memory available in RAM for message history which is evicted in time order.
  3. <lastImageSubscriptionRecoveryPolicy>:only keep the last message.
  4. <noSubscriptionRecoveryPolicy>:disable recovery of messages.
  5. <queryBasedSubscriptionRecoveryPolicy>:perform a user specific query mechanism to load any messages they may have missed.
  6. <timedSubscriptionRecoveryPolicy>:keep a timed buffer of messages around in memory and use that to recover new subscriptions.

PersistenceAdapter

http://activemq.apache.org/persistence 讲解了关于persistence的信息。ActiveMQ5.0使用AMQ Message Store 持久化消息,这种方式提供了很好的性能(The AMQ Message Store is an embeddable transactional message storage solution that is extremely fast and reliable.) 默认使用该存储方式即可,如果想使用JDBC来存储,可以查找文档配置。 

Summary

本篇文章只提供了基本配置信息。如果需要更多的文章,可以查看ActiveMQ的文档。

讲了安装和简单的配置.

本篇将通过一个实例介绍使用spring发送,消费topic, queue类型消息的方法. 不懂topic和queue的google 之.

TOPIC和QUEUE分别代表一个topic和一个queue消息通道.

  1. TopicMessageProducer向topic发送消息, TopicConsumerA和TopicConsumerB则从topic消费消息.
  2. QueueMessageProducer向Queue发送消息, QueueConsumer从Queue中消费消息

Spring整合JMS

就像对orm, web的支持一样, spring同样支持jms, 为整合jms到已有的项目提供了很多便利的方法. 本篇主要讲实战, 是所以先从配置开始, spring配置jms基本上需要8个部分.

  1. ConnectionFactory. 和jms服务器的连接, 可以是外部的jms server, 也可以使用embedded ActiveMQ Broker.
  2. Destination. 有topic和queue两种方式.
  3. JmsTemplate. spring提供的jms模板.
  4. MessageConverter. 消息转换器.
  5. MessageProducer. 消息生产者.
  6. MessageConsumer. 消息消费者.
  7. MessageListener. 消息监听器
  8. MessageListenerContainer. 消息监听容器

下面以实例的方式介绍上面8个部分.

1. ConnectionFactory

Xml代码 复制代码 收藏代码
  1. <amq:connectionFactory id="jmsConnectionFactory" brokerURL="vm://localhost" />  

 brokerURL是指要连接的activeMQ server的地址, activeMQ提供了多种brokerURL, 集体可参见文档.一般我们使用嵌套的ActiveMQ server. 配置如下, 这个配置使用消息的存储机制, 服务器重启也不会丢失消息.

Xml代码 复制代码 收藏代码
  1. <!--  embedded ActiveMQ Broker -->  
  2.     <amq:broker useJmx="false" persistent="true">  
  3.         <amq:persistenceAdapter>  
  4.             <amq:amqPersistenceAdapter directory="d:/amq"/>  
  5.         </amq:persistenceAdapter>  
  6.         <amq:transportConnectors>  
  7.             <amq:transportConnector uri="tcp://localhost:61616" />  
  8.                        <amq:transportConnector uri="vm://localhost:0" />  
  9.         </amq:transportConnectors>  
  10.     </amq:broker>  

 2. Destination

 在实例中我们使用了两种destination

Xml代码 复制代码 收藏代码
  1. <!--  ActiveMQ destinations  -->  
  2. <!--  使用topic方式-->  
  3. <amq:topic name="TOPIC" physicalName="JMS-TEST-TOPIC" />  
  4. <!--  使用Queue方式-->  
  5. <amq:queue name="QUEUE" physicalName="JMS-TEST-QUEUE" />  

 3. JmsTemplate

Xml代码 复制代码 收藏代码
  1. <!--  Spring JmsTemplate config -->  
  2.     <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">  
  3.         <property name="connectionFactory">  
  4.             <!--  lets wrap in a pool to avoid creating a connection per send -->  
  5.             <bean class="org.springframework.jms.connection.SingleConnectionFactory">  
  6.                 <property name="targetConnectionFactory" ref="jmsConnectionFactory" />  
  7.             </bean>  
  8.         </property>  
  9.         <!-- custom MessageConverter -->  
  10.         <property name="messageConverter" ref="defaultMessageConverter" />  
  11.     </bean>  

  4. MessageConverter

   MessageConverter实现的是org.springframework.jms.support.converter.MessageConverter接口, 提供消息的转换功能. DefaultMessageConverter的实现见附件.

Xml代码 复制代码 收藏代码
  1. <bean id="defaultMessageConverter" class="com.andyao.activemq.DefaultMessageConverter" />  

  5. MessageProducer

   实例拥有两个消息生产者, 消息生产者都是POJO, 实现见附件.

Xml代码 复制代码 收藏代码
  1. <!-- POJO which send Message uses  Spring JmsTemplate -->  
  2.     <bean id="topicMessageProducer" class="com.andyao.activemq.TopicMessageProducer">  
  3.         <property name="template" ref="jmsTemplate" />  
  4.         <property name="destination" ref="TOPIC" />  
  5.     </bean>  
  6.     <bean id="queueMessageProducer" class="com.andyao.activemq.QueuMessageProducer">  
  7.         <property name="template" ref="jmsTemplate" />  
  8.         <property name="destination" ref="QUEUE" />  
  9.     </bean>  

 6. MessageConsumer

 TOPIC通道有两个消息消费者, QUEUE有一个消息消费者

Xml代码 复制代码 收藏代码
  1. <!--  Message Driven POJO (MDP) -->  
  2.     <!-- consumer1 for topic a -->  
  3.     <bean id="topicConsumerA" class="com.andyao.activemq.TopicConsumerA" />  
  4.     <!-- consumer2 for topic a -->  
  5.     <bean id="topicConsumerB" class="com.andyao.activemq.TopicConsumerB" />  
  6.     <!-- consumer for queue -->  
  7.     <bean id="queueConsumer" class="com.andyao.activemq.QueueConsumer" />  

  7. MessageListener

每一个消息消费者都对应一个MessageListener

Xml代码 复制代码 收藏代码
  1. <bean id="topicListenerA" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">  
  2.         <constructor-arg ref="topicConsumerA" />  
  3.         <!--  may be other method -->  
  4.         <property name="defaultListenerMethod" value="receive" />  
  5.         <!-- custom MessageConverter define -->  
  6.         <property name="messageConverter" ref="defaultMessageConverter" />  
  7.     </bean>  
  8.   
  9.     <bean id="topicListenerB" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">  
  10.         <constructor-arg ref="topicConsumerB" />  
  11.         <!--  may be other method -->  
  12.         <property name="defaultListenerMethod" value="receive" />  
  13.         <!-- custom MessageConverter define -->  
  14.         <property name="messageConverter" ref="defaultMessageConverter" />  
  15.     </bean>  
  16.   
  17.     <bean id="queueListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">  
  18.         <constructor-arg ref="queueConsumer" />  
  19.         <!--  may be other method -->  
  20.         <property name="defaultListenerMethod" value="receive" />  
  21.         <!-- custom MessageConverter define -->  
  22.         <property name="messageConverter" ref="defaultMessageConverter" />  
  23.     </bean>  

 8. MessageListenerContainer

 有几个MessageListener既有几个MessageListenerContainer

Xml代码 复制代码 收藏代码
  1. <bean id="topicListenerContainerA" class="org.springframework.jms.listener.DefaultMessageListenerContainer">  
  2.         <property name="connectionFactory" ref="jmsConnectionFactory" />  
  3.         <property name="destination" ref="TOPIC" />  
  4.         <property name="messageListener" ref="topicListenerA" />  
  5.     </bean>  
  6.   
  7.     <bean id="topicListenerContainerB" class="org.springframework.jms.listener.DefaultMessageListenerContainer">  
  8.         <property name="connectionFactory" ref="jmsConnectionFactory" />  
  9.         <property name="destination" ref="TOPIC" />  
  10.         <property name="messageListener" ref="topicListenerB" />  
  11.     </bean>  
  12.        
  13.     <bean id="queueListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">  
  14.         <property name="connectionFactory" ref="jmsConnectionFactory" />  
  15.         <property name="destination" ref="QUEUE" />  
  16.         <property name="messageListener" ref="queueListener" />  
  17.     </bean>  

  Summary

写spring配置文件的时候, 要把MessageProducer, MessageConsumer,MessageListener,MessageListenerContainer几个地方弄清楚:

  1. 可以有一个或者多个消息生产者向同一个destination发送消息.
  2. queue类型的只能有一个消息消费者.
  3. topic类型的可以有多个消息消费者.
  4. 每个消费者对应一个MessageListener和一个MessageListenerContainer.

 

分享到:
评论
1 楼 tonytony3 2012-02-20  
应该是好文章吧,不过,入门较难

相关推荐

Global site tag (gtag.js) - Google Analytics