JMS简介
该文主要介绍了JMS的一些基本概念、常用的编程模型及消息结构,并分别介绍了PTP和Pub/Sub两种模型中常见的类。
ActiveMQ与JMS的区别与联系
Java消息服务(JMS)定义了Java中访问消息中间件的接口。JMS只是接口,并没有给予实现,实现JMS接口的消息中间件称为JMS Provider,如ActiveMQ。准确的来说JMS只是SUN为消息中间件提供的一套规范接口,具体的实现由各个厂家根据该规范去实现。ActiveMQ就是其中的一个实现。
JMS中涉及到的术语
JMS Provider:实现JMS接口的消息中间件;
PTP:Point To Point,即点对点的消息模型;
Pub/Sub:Publish/Subscribe,即发布/订阅的消息模型;
Queue:队列目标;
Topic:主题目标;
ConnectionFactory:连接工厂,JMS用它创建连接;
Connection:JMS客户端到JMS Provider的连接;
Destination:消息的目的地;
Session:会话,一个发送或接收消息的线程;
MessageProducer:由Session对象创建的用来发送消息的对象;
MessageConsumer:由Session对象创建的用来接收消息的对象;
Acknowledge:签收;
Transaction:事务。
JMS的编程模型
在 JMS 编程模型中,JMS 客户端(组件或应用程序)通过 JMS 消息服务交换消息。消息生产者将消息发送至消息服务,消息消费者则从消息服务接收这些消息。这些消息传送操作是使用一组实现 JMS 应用编程接口 (API) 的对象(由 JMS Provide提供)来执行的。
在 JMS 编程模型中,JMS 客户端使用 ConnectionFactory 对象创建一个连接,向消息服务发送消息以及从消息服务接收消息均是通过此连接来进行。Connection 是客户端与消息服务的活动连接。创建连接时,将分配通信资源以及验证客户端。这是一个相当重要的对象,大多数客户端均使用一个连接来进行所有的消息传送。
连接用于创建会话。Session 是一个用于生成和使用消息的单线程上下文。它用于创建发送的生产者和接收消息的消费者,并为所发送的消息定义发送顺序。会话通过大量确认选项或通过事务来支持可靠传送。
客户端使用 MessageProducer 向指定的物理目标(在 API 中表示为目标身份对象)发送消息。生产者可指定一个默认传送模式(持久性消息与非持久性消息)、优先级和有效期值以控制生产者向物理目标发送的所有消息。
同样,客户端使用 MessageConsumer 对象从指定的物理目标(在 API 中表示为目标对象)接收消息。消费者可使用消息选择器,借助它,消息服务可以只向消费者发送与选择标准匹配的那些消息。
消费者可以支持同步或异步消息接收。异步使用可通过向消费者注册 MessageList ener 来实现。当会话线程调用 MessageListener 对象的 onMessage 方法时,客户端将使用消息。
JMS的消息结构
消息头包含消息的识别信息和路由信息,消息头包含一些标准的属性如: JMSDesti
nation,JMSMessageID等。
消息头
消息头 | 由谁设置 |
JMSDestination | send方法 |
JMSDeliveryMode | send方法 |
JMSExpiration | send方法 |
JMSPriority | send方法 |
JMSMessageID | send方法 |
JMSTimestamp | send方法 |
JMSCorrelationI | 客户 |
JMSReplyTo | 客户 |
JMSType | 客户 |
JMSRedelivered | JMS Provider |
属性
除了消息头中定义好的标准属性外,JMS 提供一种机制增加新属性到消息头中,
这种新属性包含以下几种:
1.应用需要用到的属性;
2.消息头中原有的一些可选属性;
3. JMS Provider需要用到的属性。
标准的 JMS 消息头包含以下属性:
属性名 | 描述 |
JMSDestination | 消息发送的目的地 |
JMSDeliveryMode | 传送模式,有两种模式: PERSISTENT 和 NON_PERSISTENT,PERSISTENT 表示该消息一定要被送到目的地,否则会导致应用错误。 NON_PERSISTENT 表示偶然丢失该消息是被允许的,这两种模式使开发者可以在消息传送的可靠性和吞吐量之间找到平衡点。 |
JMSExpiration | 消息过期时间,等于 Destination 的 send 方法中的 timeToLive 值加上发送时刻的 GMT 时间值。如果 timeToLive值等于零,则 JMSExpiration 被设为零,表示该消息永不过期。如果发送后,在消息过期时间之后 消息还没有被发送到目的地,则该消息被清除。 |
JMSPriority | 消息优先级,从 0-9 十个级别,0-4 是普通消息, 5-9 是加急消息。JMS 不要求 JMS Provider 严格按照这十个优先级发送消息,但必须保证加急消息要先于普通消息到达。 |
JMSMessageID | 唯一识别每个消息的标识,由 JMS Provider 产生。 |
JMSTimestamp | 一个消息被提交给 JMS Provider 到消息被发出的时间。 |
JMSCorrelationI | 用来连接到另外一个消息,典型的应用是在回复消息中连接到原消息。 |
JMSReplyTo | 提供本消息回复消息的目的地址 |
JMSType | 消息类型的识别符 |
JMSRedelivered | 如果一个客户端收到一个设置了 JMSRedelivered 属性的消息,则表示可能客户端曾经在早些时候收到过该消息,但并没有签收(acknowledged)。 |
消息体
JMS API 定义了 5种消息体格式,也叫消息类型,可以使用不同形式发送接收数据并可以兼容现有的消息格式。
消息类型 | 消息体 |
TextMessage | java.lang.String对象,如 xml文件内容 |
MapMessage | 名/值对的集合,名是 String对象,值类型可以是 Java任何基本类型 |
BytesMessage | 字节流 |
StreamMessage | Java中的输入输出流 |
ObjectMessage | Java中的可序列化对象 |
Message | 没有消息体,只有消息头和属性 |
PTP模型
PTP(Point-to-Point)模型是基于队列的,生产者发消息到队列,消费者从队列接收消息,队列的存在使得消息的异步传输成为可能。和邮件系统中的邮箱一样,队列可以包含各种消息,JMS Provider 提供工具管理队列的创建、删除。JMS PTP 模型定义了客户端如何向队列发送消息,从队列接收消息,浏览队列中的消息。
JMS PTP 模型中的主要概念和对象:
名称 | 描述 |
ConnectionFactory | 客户端用 ConnectionFactory 创建 Connection 对象。 |
Connection | 一个到 JMS Provider 的连接,客户端可以用 Connection 创建 Session 来发送和接收消息。 |
Session | 客户端用 Session 创建 MessageProducer 和 MessageConsumer对象。如果在 Session 关闭时,有一些消息已经被收到,但还没有被签收 (acknowledged),那么,当消费者下次连接到相同的队列时,这些消息还会被再次接收。 |
Destination | (Queue客户端用 Session 创建 Destination 对象。此处或 TemporaryQueue)的目标为队列,队列由队列名识别。临时队列只能由 创建它的 Connection 所创建的消费者消费,但是任何生产者都可向临时队列发送消息。 |
MessageProducer | 客户端用 MessageProducer 发送消息到队列。 |
MessageConsumer | 客户端用 MessageConsumer 接收队列中的消息,如果用户在 receive方法中设定了消息选择条件,那么不符合条件的消息会留在队列中,不会被接收到。 |
|
|
Reliability | 可靠性, 队列可以长久地保存消息直到消费者收到消息。消费者不需要因为担心消息会丢失而时刻和队列保持激活的连接状态,充分体现了异步传输模式的优势。 |
Pub/Sub模型
JMS Pub/Sub 模型定义了如何向一个内容节点发布和订阅消息,这些节点被称作主题(topic)。主题可以被认为是消息的传输中介,发布者(publisher)发布消息到主题,订阅者(s
ubscribe) 从主题订阅消息。主题使得消息订阅者和消息发布者保持互相独立,不需要
接触即可保证消息的传送。
JMS Pub/Sub 模型中的主要概念和对象:
名称 | 描述 |
subscription | 订阅 消息订阅分为非持久订阅(non-durable subscription)和持久订阅(durable subscrip-tion),非持久订阅只有当客户端处于激活状态,也就是和 JMS Provider 保持连接状态才能收到发送到某个主题的消息,而当客户端处于离线状态,这个时间段发到主题的消息将会丢失,永远不会收到。持久订阅时,客户端向 JMS 注册一个识别自己身份的 ID,当这个客户端处于离线时,JMS Provider 会为这个 ID 保存所有发送到主题的消息,当客户再次连接到 JMS Provider时,会根据自己的 ID 得到所有当自己处于离线时发送到主题的消息。 |
ConnectionFactory | 客户端用 ConnectionFactory 创建 Connection 对象。 |
Connection | 一个到 JMS Provider 的连接,客户端可以用 Connection 创建 Session 来发送和接收消息。 |
Session | 客户端用 Session 创建 MessageProducer 和 MessageConsumer对象。它还提供持久订阅主题,或使用 unsubscribe 方法取消消息的持久订阅。 Destination(Topic客户端用 Session 创建 Destination 对象。此处和 TemporaryTopic)的目标为主题,主题由主题名识别。临时主题只能由 创建它的 Connection所创建的消费者消费。临时主题不能提供持久订阅功能。JMS 没有给 |