AlisdApacheActiveMQ笔记中国软件与技术服务股份有限公司-I-01689179ApacheActiveMQ笔记当前产品版本号v5.2最初发布日期最新修订日期2010年3月2日审核者邓建利日期批准者Apache日期AlisdApacheActiveMQ笔记-2-译者序Java是当前IT领域中比较流行的技术之一。J2EE是当前比较流行的企业级应用架构。本人一直致力于J2EE架构的学习和研究,但是总是对英文文档有不可言语的恐惧。我想很多J2EE爱好者和我有同样的感觉。这样就影响了我们深入学习J2EE原始规范的兴趣。但是J2EE原始的规范文档对我们深入理解J2EE有很大的帮助,因为它阐述了规范的来龙去脉,以及违反了规范会造成什么样的影响。了解了这些缘由和影响,会使我们对J2EE架构有更深层次的理解。这也是我做该笔记是该规范的动力所在。邓建利【Alisd】ActiveMQ官方网站:JMS官方网站:第一章.概述AlisdApacheActiveMQ笔记-3-背景当前,CORBA、DCOM、RMI等RPC中间件技术已广泛应用于各个领域。但是面对规模和复杂度都越来越高的分布式系统,这些技术也显示出其局限性:(1)同步通信:客户发出调用后,必须等待服务对象完成处理并返回结果后才能继续执行;(2)客户和服务对象的生命周期紧密耦合:客户进程和服务对象进程都必须正常运行;如果由于服务对象崩溃或者网络故障导致客户的请求不可达,客户会接收到异常;(3)点对点通信:客户的一次调用只发送给某个单独的目标对象。面向消息的中间件(MessageOrientedMiddleware,MOM)较好的解决了以上问题。发送者将消息发送给消息服务器,消息服务器将消息存放在若干队列中,在合适的时候再将消息转发给接收者。这种模式下,发送和接收是异步的,发送者无需等待;二者的生命周期未必相同:发送消息的时候接收者不一定运行,接收消息的时候发送者也不一定运行;一对多通信:对于一个消息可以有多个接收者。已有的MOM系统包括IBM的MQSeries、Microsoft的MSMQ和BEA的MessageQ等。由于没有一个通用的标准,这些系统很难实现互操作和无缝连接。JavaMessageService(JMS)是SUN提出的旨在统一各种MOM系统接口的规范,它包含点对点(PointtoPoint,PTP)和发布/订阅(Publish/Subscribe,pub/sub)两种消息模型,提供可靠消息传输、事务和消息过滤等机制。1.什么是消息中间件面向消息的中间件:Message-orientedMiddleware,MOM基本功能:将信息以消息的形式,从一个应用程序传送到另一个或多个应用程序。主要特点:消息异步接受,类似手机短信的行为,消息发送者不需要等待消息接受者的响应,减少软件多系统集成的耦合度;消息可靠接收,确保消息在中间件可靠保存,只有接收方收到后才删除消息,多个消息也可以组成原子事务。AlisdApacheActiveMQ笔记-4-消息中间件的主要应用场景:公司在发展过程中,开发(或者购买了)多套企业信息系统,比如财务系统,人事系统,在线销售系统,运营系统等。这些系统生产/消费公司的各种业务数据。公司需要将这些系统集成(整合),比如让在线销售系统的订单数据输入到财务系统中。类似应用的一般系统需求是:可靠传输,数据不能丢失,有的时候,也会要求不能重复传输;异步传输,否则各个系统同步发送接受数据,互相等待,造成系统瓶颈。公司可以为此开发自己的软件服务,代价会比较大,现在一般使用已经成型的消息中间件。目前比较知名的消息中间件:IBMMQSeriesBEAWebLogicJMSServerOracleAQTibcoSwiftMQAcitveMQ:是免费的java实现的消息中间件什么是JMSJMSJavaMessageService,Java消息服务。AlisdApacheActiveMQ笔记-5-JMS概述1.1.1.JMS规范JAVA消息服务(JMS)定义了Java中访问消息中间件的接口。JMS只是接口,并没有给予实现,实现JMS接口的消息中间件称为JMSProvider,例如ActiveMQ。1.1.2.术语JMSProvider:实现JMS接口的消息中间件;PTP:PointtoPoint,即点对点的消息模型;Pub/Sub:Publish/Subscribe,即发布/订阅的消息模型;Queue:队列目标;Topic:主题目标;ConnectionFactory:连接工厂,JMS用它创建连接;Connection:JMS客户端到JMSProvider的连接;Destination:消息的目的地;Session:会话,一个发送或接收消息的线程;MessageProducer:由Session对象创建的用来发送消息的对象;MessageConsumer:由Session对象创建的用来接收消息的对象;Acknowledge:签收;Transaction:事务。1.1.3.JMS编程模型在JMS编程模型中,JMS客户端(组件或应用程序)通过JMS消息服务交换消息。消息生产者将消息发送至消息服务,消息消费者则从消息服务接收这些消息。这些消息传送操作是使用一组实现JMS应用编程接口(API)的对象(由JMSProvide提供)来执行的。在JMS编程模型中,JMS客户端使用ConnectionFactory对象创建一个连接,向消息服务发送消息以及从消息服务接收消息均是通过此连接来进行。Connection是客户端与消息服务的活动连接。创建连接时,将分配通信资源以及验证客户端。这是一个相当重要的对象,大多数客户端均使用一个连接来进行所有的消息传送。连接用于创建会话。Session是一个用于生成和使用消息的单线程上下文。它用于创建发送的生产者和接收消息的消费者,并为所发送的消息定义发送顺序。会话通过大AlisdApacheActiveMQ笔记-6-量确认选项或通过事务来支持可靠传送。客户端使用MessageProducer向指定的物理目标(在API中表示为目标身份对象)发送消息。生产者可指定一个默认传送模式(持久性消息与非持久性消息)、优先级和有效期值,以控制生产者向物理目标发送的所有消息。同样,客户端使用MessageConsumer对象从指定的物理目标(在API中表示为目标对象)接收消息。消费者可使用消息选择器,借助它,消息服务可以只向消费者发送与选择标准匹配的那些消息。消费者可以支持同步或异步消息接收。异步使用可通过向消费者注册MessageListener来实现。当会话线程调用MessageListener对象的onMessage方法时,客户端将使用消息。1.1.4.JMS编程域JMS支持两种截然不同的消息传送模型:PTP(即点对点模型)和Pub/Sub(即发布/订阅模型),分别称作:PTPDomain和Pub/SubDomain。PTP(使用Queue即队列目标)消息从一个生产者传送至一个消费者。在此传送模型中,目标是一个队列。消息首先被传送至队列目标,然后根据队列传送策略,从该队列将消息传送至向此队列进行注册的某一个消费者,一次只传送一条消息。可以向队列目标发送消息的生产者的数量没有限制,但每条消息只能发送至、并由一个消费者成功使用。如果没有已经向队列目标注册的消费者,队列将保留它收到的消息,并在某个消费者向该队列进行注册时将消息传送给该消费者。Pub/Sub(使用Topic即主题目标)消息从一个生产者传送至任意数量的消费者。在此传送模型中,目标是一个主题。消息首先被传送至主题目标,然后传送至所有已订阅此主题的活动消费者。可以向主题目标发送消息的生产者的数量没有限制,并且每个消息可以发送至任意数量的订阅消费者。主题目标也支持持久订阅的概念。持久订阅表示消费者已向主题目标进行注册,但在消息传送时此消费者可以处于非活动状态。当此消费者再次处于活动状态时,它将接收此信息。如果没有已经向主题目标注册的消AlisdApacheActiveMQ笔记-7-费者,主题不保留其接收到的消息,除非有非活动消费者注册了持久订阅。这两种消息传送模型使用表示不同编程域的API对象(其语义稍有不同)进行处理,如下所示:使用图表第一列中列出的统一域对象编写点对点和发布/订阅消息传送。这是首选方法(JMS1.1规范)。然而,为了符合早期的JMS1.02b规范,可以使用PTP域对象编写点对点消息传送,使用Pub/Sub域对象编制发布/订阅消息传送。JMS消息结构JMS消息由以下几部分组成:消息头,属性和消息体。1.1.5.消息头(Header)消息头包含消息的识别信息和路由信息,消息头包含一些标准的属性如:JMSDestination,JMSMessageID等。如何设置消息头的字段:消息头由谁设置JMSDestinationsend方法JMSDeliveryModesend方法JMSExpirationsend方法JMSPrioritysend方法JMSMessageIDsend方法JMSTimestamp客户端JMSCorrelationID客户端JMSReplyTo客户端JMSType客户端JMSRedeliveredJMSProvider标准的JMS消息头包含以下属性:AlisdApacheActiveMQ笔记-8-消息头描述分配方式JMSDestination消息发送的目的地:主要是指Queue和Topic。自动JMSDeliveryMode传送模式有两种模式:持久模式和非持久模式。一条持久性的消息应该被传送“一次仅仅一次”,这就意味者如果JMS提供者出现故障,该消息并不会丢失,它会在服务器恢复之后再次传递。一条非持久的消息最多会传送一次,这意味这服务器出现故障,该消息将永远丢失。自动JMSExpiration消息过期时间,等于Destination的send方法中的timeToLive值加上发送时刻的GMT时间值。如果timeToLive值等于零,则JMSExpiration被设为零,表示该消息永不过期。如果发送后,在消息过期时间之后消息还没有被发送到目的地,则该消息被清除。自动JMSPriority消息优先级,从0-9十个级别,0-4是普通消息,5-9是加急消息。JMS不要求JMSProvider严格按照这十个优先级发送消息,但必须保证加急消息要先于普通消息到达。默认是4级。自动JMSMessageID唯一识别每个消息的标识,由JMSProvider产生。自动JMSTimestamp一个JMSProvider在调用send()方法时自动设置的。它是消息被发送和消费者实际接收的时间差。自动JMSCorrelationID用来连接到另外一个消息,典型的应用是在回复消息中连接到原消息。在大多数情况下,JMSCorrelationID用于将一条消息标记为对JMSMessageID标示的上一条消息的应答,不过,JMSCorrelationID可以是任何值,不仅仅是JMSMessageID。开发者设置JMSTimestamp一个消息被提交给JMS自动AlisdApacheActiveMQ笔记-9-Provider到消息被发出的时间。JMSReplyTo提供本消息回复消息的目的地址。开发者设置JMSType消息类型的识别符。开发者设置JMSRedelivered如果一个客户端收到一个设置了JMSRedelivered属性的消息,则表示可能客户端曾经在早些时候收到过该消息,但并没有签收(acknowledged)。如果该消息被重新传送,JMSRedelivered=true反之,JMSRedelivered=false。自动1.1.6.消息体(Body)JMSAPI定义了5种消息体格式,也叫消息类型,可以使用不同形式发送接收数据并可以兼容现有的消息格式