JMS与ActiveMQ简介(一)

一、简介

        Java 消息服务(Java Message Service,简称JMS)是Java平台上有关面向消息中间件(MOM)的技术规范。JMS 在其中扮演的角色与JDBC 很相似,正如JDBC 提供了一套用于访问各种不同关系数据库的公共API,JMS也提供了独立于特定厂商的企业消息系统访问方式,Java提供一个接口让不同的厂商去实现,常见的实现有ActiveMQ、JBoss MQ、IBM Websphere MQ等。其中当下最流行的就是ActiveMQ

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

         JMS 的编程过程很简单,概括为:应用程序A 发送一条消息到消息服务器(也就是JMS Provider)的某个目得地(Destination),然后消息服务器把消息转发给应用程序B。因为应用程序A 和应用程序B 没有直接的代码关连,所以两者实现了解偶。如下图:


JMS与ActiveMQ简介(一)
 

二.消息的组成

在JMS系统中最核心的就是消息。一条Message 由三个部分组成:

  • 头(head)

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

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

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

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

  • 属性(property)

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

  •  主体(body)

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

  1. StreamMessage   一种主体中包含Java基元值流的消息。其填充和读取均按顺序进行。
  2. MapMessage       一种主体中包含一组键--值对的消息。没有定义条目顺序。
  3. TextMessage       一种主体中包含Java字符串的消息(例如,XML消息)。
  4. ObjectMessage    一种主体中包含序列化Java对象的消息。
  5. BytesMessage     一种主体中包含连续字节流的消息。

三、消息的传递模型

JMS支持两种消息传递模型:基于队列(Queue)点对点模型和基于主题(Topic)发布/订阅模型。这两种消息传递模型非常相似,但有以下区别:

  1.  Queue消息传递模型规定了一条消息只能够传递给一个消费者。
  2. Topic消息传递模型允许一条消息传递给多个消费者

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

3.1点对点的消息传递模型

通过点对点的消息传递模型,一个应用程序可以向另外一个应用程序发送消息。在此传递模型中,目标类型是队列。消息首先被传送至队列目标,然后从该队列将消息传送至对此队列进行监听的某个消费者,如下图:


JMS与ActiveMQ简介(一)
 一个队列可以关联多个队列发送方和接收方,但一条消息仅传递给一个接收方。如果多个接收方正在监听队列上的消息,JMS Provider将根据“先来者优先”的原则确定由哪个接收方接受下一条消息。如果没有接收方在监听队列,消息将保留在队列中,直至接收方连接到队列为止。

温馨提示:在此列模型中,消息不会自动推给给客户端,而是要求客户端从队列中请求获得。

3.2发布/订阅消息传递模型

通过发布/订阅消息传递模型,应用程序能够将一条消息发送到多个接收方。在此传送模型中,目标类型是主题。消息首先被传送至主题目标,然后传送至所有已订阅此主题的送消费者。如下图:


JMS与ActiveMQ简介(一)
 主题目标也支持长期订阅。长期订阅表示消费者已注册了主题目标,但在消息到达目标时该消费者可以处于非活动状态。当消费者再次处于活动状态时,将会接收该消息。如果消费者均没有注册某个主题目标,该主题只保留注册了长期订阅的非活动消费者的消息。与点对点消息传递模型不同,发布/订阅消息传递模型允许多个主题订阅者接收同一条消息。JMS一直保留消息,直至所有主题订阅者都接收到消息为止。

温馨提示:在该模型中,消息会自动广播,消费者无须通过主动请求或轮询主题的方法来获得新的消息。

上面两种消息传递模型中,我们都需要定义消息生产者和消费者,生产者把消息发送到JMS Provider的某个目标地址(Destination),消息从该目标地址传送至消费者。消费者可以同步或异步接收消息,一般而言,异步消息消费者的执行和伸缩性都优于同步消息接收者,体现在:

  1. 异步消息接收者创建的网络流量比较小。
  2. 异步消息接收者使用线程比较少。异步消息接收者在不活动期间不使用线程。同步消息接收者在接收调用期间内使用线程,结果线程可能会长时间保持空闲,尤其是如果该调用中指定了阻塞超时。
  3. 对于服务器上运行的应用程序代码,使用异步消息接收者几乎总是最佳选择,尤其是通过消息驱动Bean。使用异步消息接收者可以防止应用程序代码在服务器上执行阻塞操作。而阻塞操作会是服务器端线程空闲,甚至会导致死锁。阻塞操作使用所有线程时则发生死锁。如果没有空余的线程可以处理阻塞操作自身解锁所需的操作,这该操作永远无法停止阻塞。

四.JMS Provider(ActiveMQ)的特性与优势

  1. 实现JMS1.1规范,支持J2EE1.4以上。
  2. 可运行与任何JVM和大部分web容器(ActiveMQ works great in any JVM)
  3. 支持多种语言客户端(java, C, C++, Ajax, ActionScript等等)
  4. 支持多种协议(stomp, openwire, REST)
  5. 良好的Spring支持(ActiveMQ has great Spring Support)
  6. 速度很快,JBossMQ的十倍(ActiveMQ is very fast; often 10x faster than JBossMQ)
  7. 与OpenJMS、JBossMQ等开源jms provider相比,ActiveMQ有apache的支持,持续发展的优势明显

五、Queue与Topic的比较

  •   JMS Queue(队列)

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

  •  JMS Topic(发布/订阅)

    一条消息被publish(发布)时,他将发送给所有感兴趣的订阅者,所以零到多个subscriber(订阅者)将接收到消息的一个拷贝。但是在消息代理接收到消息时,只有激活订阅的subscriber能够获得消息的一个拷贝。根据订阅的处理方式不同,分为非持久化订阅与持久化订阅两种消息处理方式。

相关推荐