[JMS] ActiveMQ -- 入门

消息中间件(MOM): 交换信息的一类软件。当分布式应用使用MOM后,分布式应用会得到的好处是:松耦合、可靠、可扩展、安全。

 

ActiveMQ 就是一个MOM 。ActiveMQ 遵守JMS 规范,使用ActiveMQ 是JMS的一个提供者。

 

一    ActiveMQ 的特征


    1 遵守JMS 规范
    2 连接性:支持多协议传递消息,可以和jee容器整合。
    3 可插拔的持久化和安全组件:消息可以被持久化(存储),可以支持KahaDB和jdbc;可以完成验证用户的身份和授权。
    4 使用java创建消息应用程序
    5 可以与Java 应用服务器整合
    6 客户端API:客户端可以使用不同的语言来编写。
    7 Broker 集群:这个的borker 我个人认为就是一个mq 的消息处理程序,就是一群mq 一起工作。
    8 一些高级的broker 特性和客户端选项
    9 动态的简化管理:提供管理工具,管理active mq

 

二    什么时候应用Active MQ


    1 使用不同语言写的应用程序之间的整合:ActiveMQ broker 是使用Java 语言写的,但是mq 也支持不同的语言访问mq。
    2 替代RPC
    3 应用之间松散耦合
    4 可以作为一个事件驱动架构的基础

    总体上看,消息是一个业务信息单元,应用之间通过MOM 传递这个消息。应用通过MOM的destinations来发送和接收消息。
异步消息:发送者和接收者不用同时在线,并且发送者和接收者相互不知道。

 

MOMs 添加了额外的通用功能:
        1 消息的持久化;
        2 当使用不稳定的或者慢的网络时,可以保证稳定的通信;
        2 复杂的消息路由,包括把一个消息发送给多个接收者。
        3 消息转换,可以实现消息格式的转换。当两个程序不能处理同一格式的消息时使用。

 

三    JMS 中定义的概念:


     1 JMS 客户端:一个应用100% 使用java 写。 主要使用MessageProducer 和MessageConsumer 接口。
     2 非JMS 客户端:使用本地API 的应用。
     3 JMS producer: 创建和发送jms 的一个应用
     4 JMS consumer: 接收和处理jms 的一个应用
     5 JMS 提供者:实现JMS 接口,被客户端使用来发送和接收消息的。这个就是active mq。
     6 JMS 消息:JMS 发送和接收的信息。
     7 JMS 域:两种消息的类型,point-to-point 和 publish-subscribe
     8 被管理的对象:提前被配置好的JMS 对象们(实例),这些对象包含了用户的特殊配置。一般客户端可以通过JNDI访问这些对象。
     9 连接工厂:客户端使用连接工厂来创建连接,客户端通过连接访问JSM 提供者(就是Active mq)。
     10 Destination(目的地):发送消息给这个对象,或者通过这个对象接收消息。

 

MessageProducer 类提供了以下功能: 1 发送消息  2 设置消息头,包括JMSDeliveryMode,JMSPriority 和JMSExpiration(通过get/setTimeToLive 方法)。
MessageConsumer 类可以从一个目的地接收消息,可以使用receive() 方法同步的接收信息,也可以使用MessageListener 对象异步的接收信息。

 

四    JMS 消息的结构 


    JMS 消息由两部分组成,消息头和负载。消息头提供元数据,该元数据被JMS 提供者和两头的客户端使用(这里指的是接收和发送消息的客户端们)。负载实际上就是消息体,消息体可以携带文本数据或二进制数据。参见图1.

 

 

                图 1

 

 

消息头中的信息很复杂,可以分为两种:
           1  headers(头信息): JMS 规范定义的头信息
           2  properties(属性信息):客户可以定义的头信息

 

1 我们先介绍headers(头信息):

    当客户端调用send() 方法时,被自动设置的头信息为:


        JMSDestination:这个消息要发送到的目的地。这个对象,对于想从这个destination 中得到信息的客户端很重要。


        JMSDeliveryMode:JMS 支持两种发送消息的模式,持久的和非持久的。默认的方式是持久的。
        持久表示的含义:建议JMS 提供者持久化JMS 消息。如果提供者失败了,消息不会丢失。一个JMS 提供者必须保证发送一个持久的信息“一次且仅一次”。这样设置,表明可靠性比性能更重要。
        非持久表示的含义:建议JMS 的提供者不要持久化消息。一个提供者必须发送一个非持久化的消息“最多一次”。换句话说,就是如果提供者失败,消息可能丢失,但是一个不能被发送两次。


        JMSExpiration:消息过期的时间。这个头信息被设置,防止JMS 提供者发送过期的消息。可以通过MessageProducer.setTimeToLive() 来设定全局的值。也可以通过MessageProducer.send() 方法来为特殊消息指定特殊的值。默认值为0,表示消息不会过期。这个消息头的值=“time-to-live” + “当前时间”,时间是以GMT(格林尼治标准时间)为基准。
        JMSMesaageID:每一个消息都有一个唯一的ID。这个ID 由JMS 提供者分配。可以在客户端通过MessageProducer.setDisableMessageID() 方法来建议提供者不要设定ID 值。当性能重要的时候,可以考虑这个设置。
        JMSPriority:指定消息的重要等级。这个头信息通过producer 设定全局的值,可以通过producer 的send() 方法指定一个消息的特殊值。一共10个等级,从0到9。0到4 为一般等级,5-9 为加速等级。
        JMSTimestamp:这个值记录了消息被从producer 发送给JMS 提供者的时间。可以通过MessageProducer.setDisableMassageTimestamp() 方法来建议JMS 提供者不要设定这个值。这个值可能是一个提供者的消息ID,可能是一个程序设定的字符串,或者一个本地的byte[] 值。

 

    客户端可以设定的头信息为:
        JMSCorrelationID:为当前的消息关联一个先前的消息,这里的值就是先前消息的ID。这个头信息通常被用来完成request 和response (请求和相应)消息的关联。


        JMSReplyTo:指定一个destination(目的地),一个回复信息应该被发送到这个目的地。这个一般被于请求/回答(request/reply)风格的消息。


        JMSType:


    JMS 提供者可以设定的:
    JMSRedelivered:


   
2 properties(属性) 头信息

    JMS 规范保留了JMSX property 名称前缀,所以看到JMSX 开头的属性,都是JMS 规范定义的。
    Message 类提供了一些方法,可以让客户端定义自己的属性。

    举一个例子说明头信息的用途:

         消息选择器(Message selectors)
         有时候JMS 客户端只想接收目的地(destination)的特定信息,可以通过消息选择器来实现这个需求。定义选择器时,必须根据headers 和properties 中的信息

定义。
         String selector = "SYMBOL = 'AAPL'";
         MessageConsumer consumer = session.createConsumer(destination, selector);

         表示consumer 指接收properties 中,SYMBOL=AAPL 的消息。

 

 

 

3  消息体:真正存放数据和信息的地方


    JMS 定义了6种类型的消息体,消息体有时也被称为负载。通过使用下列对象,可以通过负载发送数据和信息。
          Message 低级的消息类型,发送一个没有消息体的消息。一般用于简单的事件通知
          TextMessage 负载是一个字符串,一般用于发送简单文本和XML 数据。
          MapMessage 负载是一个键值对,名字和值都必须是Java的基本类型
          ByteMessage 负载是一个二进制数组
          StreamMessage 负载是一个基本java 类型的流
          ObjectMessage 负载是一个可序列化的Java 对象。通常是一个复杂的java 对象。也支持Java 集合。

 

 

五    JMS 域

     JMS 有两种方式,点对点(point-to-point),发布/订阅。
   

     (1)点对点的方式:可以把目的地(destinations) 想像成队列,通过使用这个队列,消息可以同步或异步的传递。每个被队列接收的消息都被一次仅一次给消费者(consumer)。参见图2.
              同步接收消息:  MessageConsumer.recerve();
              异步接收消息:  MessageConsumer.setMessageListener(MessageListener);
              发送到队列的消息将被存储。直到消息被传送给消费者或者消息过期,这个消息才被从队列中移除。
     多个生产者,多个消费者(consumer) 能够注册到同一个队列上。但是一个消息只能被一个consumer 接收。(这是点对点的由来)

 

                                       图  2

 

     (2)发布/订阅(Publish/Subscribe) 方式:把目的地看作为topics(主题)。任何发送给主题的消息都被自动的传递给所有的消费者。这个消息域和邮件列表和相似。参加图3.
              同步接收消息:  MessageConsumer.recerve();
              异步接收消息:  MessageConsumer.setMessageListener(MessageListener);
      主题不会保存消息,除非你告诉它保存。可以通过用“耐久订阅(durable subsrciption)”来实现保存消息。当你使用耐久订阅时,一个订阅者断开了与JMS 提供者的连接,JMS 提供者负责存储应该给这个订阅者的消息,当这个订阅者重新建立连接后,订阅者可以接收到它应该接收到的消息(如果在断开的过程中,如果消息已经过期,那么消息将不会被接收)。

 

                                               图 3

 

注意:消息的耐久性(durability)与持久性(persistence)的区别
     1  耐久性只能被应用到pub/sub 域中。
     2  消息持久性独立于消息域。消息持久性是一个服务质量属性,用来显示JMS 应用有能力处理JMS 提供者失败的事件。设置方法是消息的产生者的setDeliveryMode() 方法,参数为JMSDeliveryMode.PERSISTENT or JMSDeliveryMode.NON-PERSISTENT。

 

     (3)Request/reply 消息域:
      尽管JMS 没有正式定义Request/reply 消息域,但是JMS 提供了一些消息头和一对类来实现request/reply 消息。

 

六    被管理的对象

 

    被管理的对象包含提供者的特殊配置信息,由JMS 管理员创建它。然后,JMS 客户端来使用它。它被用来隐藏JMS 提供者的细节,抽象了JMS 提供者的管理任务。一般情况下,客户端使用JNDI 来得到被管理的对象。

    JMS 规范定义了两种类型的被管理对象:ConnectionFactory 和Destination。

    ConnectionFactory(连接工厂):JMS 客户端使用ConnectionFactory 对象创建一个到JMS 提供者的连接。连接通常表示一个被打开的TCP socket,所以一个连接是消耗系统资源的。可以考虑使用连接池来重用连接。这里的连接和JDBC 的连接很相似。客户端可以使用JMS 连接创建javax.jms.Session 对象,这个对象表示客户端与JMS 提供者的一个相互作用。

 

     Destination(目的地):目的地封装了一个提供者的地址,消息可以发送到这个地址,也可以从这个地址被读取。虽然我们通过Session 对象创建Destinations,但是Destination 对象的生命周期和创建Session 的Connection 对象的生命周期是一致的。

 

 

参考:本文是读<<ActiveMQ in Action>> 第2章后,做的笔记。可以在网络上下载到这本书。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值