Apache ActiveMQ教程

参考1:
http://wenku.baidu.com/link?url=C9O2bKNOAIz2pZDeortvH6uPOegmYr_7il7P8b8VHzORoGC-M-3A1MPqDyNQQ6WxqBtGHmiI3M_hSVyniHRGKqZkhxrOKnV1hma0Ft3sMa3


参考2:
http://boy00fly.iteye.com/blog/1103586

1. JMS架构

Java 消息服务(Java Message Service,简称JMS)是用于访问企业消息系统的开发商中立的API。企业消息系统可以协助应用软件通过网络进行消息交互。JMS 在其中扮演的角色与JDBC 很相似,正如JDBC 提供了一套用于访问各种不同关系数据库的公共API,JMS 也提供了独立于特定厂商的企业消息系统访问方式。

使用JMS 的应用程序被称为JMS 客户端,处理消息路由与传递的消息系统被称为JMS Provider,而JMS 应用则是由多个JMS 客户端和一个JMS Provider 构成的业务系统。发送消息的JMS 客户端被称为生产者(producer),而接收消息的JMS 客户端则被称为消费者(consumer)。同一JMS 客户端既可以是生产者也可以是消费者。

一条Message 由三个部分组成:
1. 头(head)

每条JMS 消息都必须具有消息头。头字段包含用于路由和识别消息的值。可以通过多种方式来设置消息头的值:

a. 由JMS 提供者在生成或传送消息的过程中自动设置

b. 由生产者客户机通过在创建消息生产者时指定的设置进行设置

c. 由生产者客户机逐一对各条消息进行设置



2. 属性(property)

消息可以包含称作属性的可选头字段。他们是以属性名和属性值对的形式制定的。可以将属性是为消息头得扩展,其中可以包括如下信息:创建数据的进程、数据的创建时间以及每条数据的结构。JMS提供者也可以添加影响消息处理的属性,如是否应压缩消息或如何在消息生命周期结束时废弃消息。



3. 主体(body)

包含要发送给接收应用程序的内容。每个消息接口特定于它所支持的内容类型。JMS为不同类型的内容提供了他们各自的消息类型,但是所有消息都派生自Message接口。

StreamMessage   一种主体中包含Java基元值流的消息。其填充和读取均按顺序进行。

MapMessage     一种主体中包含一组键--值对的消息。没有定义条目顺序。

TextMessage       一种主体中包含Java字符串的消息(例如,XML消息)。

ObjectMessage    一种主体中包含序列化Java对象的消息。

BytesMessage     一种主体中包含连续字节流的消息。

MapMessage={
    Header={
        ... standard headers ...
        CorrelationID={123-00001}
    }
    Properties={
        AccountID={Integer:1234}
    }
    Fields={
        Name={String:Mark}
        Age={Integer:47}
    } 
}


消息的传递模型

点对点(point-to-point,简称PTP) 1:1

发布/订阅(publish/subscribe,简称pub/sub) 1:n

每个模型都通过扩展公用基类来实现。例如:javax.jms.Queue和Javax.jms.Topic都扩展自javax.jms.Destination(目的)类。

1. 点对点消息传递

一个队列可以关联多个队列发送方和接收方,但一条消息仅传递给一个接收方。如果多个接收方正在监听队列上的消息,JMS Provider将根据“先来者优先”的原则确定由哪个价售房接受下一条消息。如果没有接收方在监听队列,消息将保留在队列中,直至接收方连接到队列为止。这种消息传递模型是传统意义上的拉模型或轮询模型。在此列模型中,消息不时自动推动给客户端的,而是要由客户端从队列中请求获得。

2. 发布/订阅消息传递

主题目标也支持长期订阅。长期订阅表示消费者已注册了主题目标,但在消息到达目标时改消费者可以处于非活动状态。当消费者再次处于活动状态时,将会接收该消息。如果消费者均没有注册某个主题目标,该主题只保留注册了长期订阅的非活动消费者的消息。与PTP消息传递模型不同,pub/sub消息传递模型允许多个主题订阅者接收同一条消息。JMS一直保留消息,直至所有主题订阅者都接收到消息为止。pub/sub消息传递模型基本上时一个推模型。在该模型中,消息会自动广播,消费者无须通过主动请求或轮询主题的方法来获得新的消息。


生产者吧消息发送到JMS Provider的某个目标地址(Destination),消息从该目标地址传送至消费者。消费者可以同步或异步接收消息,一般而言,异步消息消费者的执行和伸缩性都优于同步消息接收者,体现在:

1. 异步消息接收者创建的网络流量比较小
2. 异步消息接收者使用线程比较少。
3.对于服务器上运行的应用程序代码,使用异步消息接收者几乎总是最佳选择,尤其是通过消息驱动Bean。


2. JMS Provider(ActiveMQ)
Queue与Topic的比较
1. JMS Queue执行load balancer语义

    一条消息仅能被一个consumer收到。如果在message发送的时候没有可用的consumer,那么它讲被保存一直到能处理该message的consumer可用。如果一个consumer收到一条message后却不响应它,那么这条消息将被转到另外一个consumer那儿。一个Queue可以有很多consumer,并且在多个可用的consumer中负载均衡。

2. Topic实现publish和subscribe语义

    一条消息被publish时,他将发送给所有感兴趣的订阅者,所以零到多个subscriber将接收到消息的一个拷贝。但是在消息代理接收到消息时,只有激活订阅的subscriber能够获得消息的一个拷贝。

Point-to-Point(点对点)消息模式开发流程

代码请参看:
http://boy00fly.iteye.com/blog/1103586
3. JMS For Spring

1. Spring 配置 connectionFactory
<!--客户端使用普通传输方式:tcp://localhost:61616 
	此处需加以注意的是Listener端的borkerURL使用了failover传输方式: 
	failover:(tcp://localhost:61616)?initialReconnectDelay=100&amp;
maxReconnectAttempts=5 
	failover transport是一种重新连接机制,用于建立可靠的传输。此处配置的是一旦ActiveMQ broker中断,Listener端将每隔100ms自动尝试连接,直至成功连接或重试5次连接失败为止。
	failover还支持多个borker同时提供服务,实现负载均衡的同时可增加系统容错性,格式: failover:(uri1,...,uriN)?transportOptions
-->
<bean id="jmsFactory" destroy-method="stop" class="org.apache.activemq.pool.PooledConnectionFactory">
		<property name="connectionFactory">
			<bean class="org.apache.activemq.ActiveMQConnectionFactory">
				<property name="brokerURL" value="tcp://localhost:61616" />
                 <property name="userName" value="${activemq.username}" />
				<property name="password" value="${activemq.password}" />
			</bean>
		</property>
</bean>





2. Spring JmsTemplate
<!-- Spring JMS Template
		JmsTemplate 类的实例 一经配置便是线程安全 的。 要清楚一点,JmsTemplate 
		是有状态的,因为它维护了 ConnectionFactory 的引用,但这个状态时不是会话状态。
-->
	<bean id="myJmsTemplate"
		class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory" ref="jmsFactory" />
		<property name="defaultDestinationName" value="MySubject" />
		<!--JMS API有两种发送方法,一种采用发送模式、
优先级和存活时间作为服务质量(QOS)参数,
			默认{deliveryMode:2(1),priority:4,timeToLive:0}
			另一种使用无需QOS参数的缺省值方法。
			<property name="explicitQosEnabled" value="true"/>
			<property name="deliveryMode" value="2"/>
			<property name="priority" value="4"/>
                        <property name="timeToLive" value="1000"/>
		 -->
		<!--
		 	<property name="receiveTimeout" value="1000" />
		 -->
	</bean>



3. 发送的接收消息
<bean id="destinationTopic"
		class="org.apache.activemq.command.ActiveMQTopic">
		<constructor-arg index="0" value="HelloWorldTopic" />
	</bean>
	<!-- 读取信息 -->
	<bean id="consumer" class="com.d1xn.jms.demo.Consumer">
		<property name="jmsTemplate" ref="myJmsTemplate" />
	</bean>

	<!-- 发送信息 -->
	<bean id="producerTopic" class="com.d1xn.jms.demo.ProducerTopic">
		<property name="jmsTemplet" ref="myJmsTemplate" />
		<property name="destination" ref="destinationTopic" />
	</bean>
	<!-- 消息监听 -->

	<bean id="listenerContainerTopic"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="jmsFactory" />
		<property name="destination" ref="destinationTopic" />
		<property name="messageListener" ref="consumer" />
         <!—持久化客户端ID -->
		<property name="clientId" value="clientId_001" />
		<property name="subscriptionDurable" value="true" />
		<property name="durableSubscriptionName" value="My_001" />
</bean>

你可能感兴趣的:(activemq)