JMS - Message

一条 JMS 消息包含三个部分:消息头、消息属性和消息体。

 

消息头

  消息头提供了和消息有关的元数据,它描述了消息有谁创建、何时创建、数据的有效长度等信息。消息头还包含了描述消息目的地(主题或队列)的路由信息、消息如何被确认等另外一些信息。

JMSDestination

  JMSDestination 消息头使用一个 Queue 或 Topic 对象类标识目的地,二者都是 Destination 类型。对于从一个以上的队列或主题中消费消息的 JMS 客户端来说,识别消息的目的地是非常重要的。

Queue destination = (Queue) message.getJMSDestination();

JMSDeliveryMode

  在 JMS 中,传送模式有两种类型:持久性模式和非持久性模式。一条持久性消息应该被传送一次而且仅有一次,这就意味着如果 JMS 提供者出现故障,该消息并不会丢失;它会在服务器恢复正常之后再次传送。一条非持久性消息最多只会传送一次,这意味着如果 JMS 提供者出现故障,该消息可能会永远丢失。在持久性和非持久性这两种传送模式中,消息服务器都不会将一条消息向同一消费者发送一次以上。

int deliveryMode = message.getJMSDeliveryMode();
if (deliveryMode == DeliveryMode.PERSISTENT) {
    
} else {    // DeliveryMode.NON_PERSISTENT
    
}

  传送模式可以使用生产者(也就是 TopicPublisher 或 QueueSender)上的 setJMSDeliveryMode() 方法来设定。一旦为 MessageProducer 设置了传送模式,它就会应用到使用该生产者传送的所有消息上。默认设置为 DeliveryMode.PERSISTENT。

MessageProducer producer = session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

JMSMessageID

  JMSMessageID 是一个 String 类型值,它唯一地标识了一条消息。JMSMessageID 对 JMS 中消费者应用程序中的历史仓库(repositories)来说非常有用,它是仓库中的消息需要的唯一索引。JMSMessageID 还可以与 JMSCorrelationID 结合使用,用于关联消息。

String messageID = message.getJMSMessageID();

JMSTimestamp

  JMSTimestamp 由 MessageProducer 在调用 send() 操作时自动设置。它包含的是 JMS 提供者接收消息的时间,而不是该消息实际传送的时间。这个消息头用于确定发送消息和它被消费者实际接收的时间间隔。

long timestamp = message.getJMSTimestamp();

JMSExpiration

  一个 Message 对象的有效期(expiration date)用来防止把过期的消息传送给消费者。这对于那些数据仅在某一时间段内有效的消息来说,是非常有用的:

long timeToLive = message.getJMSExpiration();

  消息的有效期以毫秒为单位,在生产者使用 setTimeToLive() 方法设置:

MessageProducer producer = session.createProducer(destination);
producer.setTimeToLive(24 * 3600 * 1000);

  提供者将 timeToLive 值添加到系统时间戳中,并对 JMSExpiration 进行设置。使用参数 0 调用 setTimeToLive(),能够确保创建一条不设有效期的消息。在消息发送出去之后,任何直接通过编程方式来调用 setJMSExpiration() 方法都会被忽略。

JMSRedelivered

  JMSRedelivered 消息头表示该消息将被重新传送给消费者。如果一个消费者未能确认先前传送的消息,或者 JMS 提供者并不能确定消费者是否已经接收到该消息时,就可以将这条消息标记为重新发送。

boolean isRedelivered = message.getJMSRedelivered();

JMSPriority

  在传送一条消息时,消息生产者能够为该消息分配一个优先级。优先级取值范围为 0~9,数值越高,优先级越高。

int priority = message.getJMSPriority();

  消息的优先级可以通过 JMS 客户端在生产者上使用 setPriority() 方法进行设置:

MessageProducer producer = session.createProducer(destination);
producer.setPriority(9);

  在消息发送出去之后,任何直接通过编程方式来调用 setJMSPriority() 方法都会被忽略。

JMSReplyTo

  有些情况下,一个 JMS 消息生产者可能会要求消费者对一条消息做出应答。 JMSReplyTo 消息头包含了一个 javax.jms.Destination,标明了 JMS 消费者应该应答的地址。在使用请求/响应场景时,通过这条消息头属性可以进一步实现消息生产者和消息消费者之间的去耦。

JMSCorrelationID

  JMSCorrelationID 用于将前的消息和先前的某些消息或应用程序特定的 ID 关联起来。在大多数情况下,JMSCorrelationID 用于将一条消息标记为对 JMSMessageID 标识的上一条消息的应答,不过,JMSCorrelationID 可以是任何值,而不仅仅是 JMSMessageID。

JMSType

  JMSType 是由 JMS 客户端设置的一个可选消息头。它的主要作用是标识消息结构和有效负载的类型。请注意,这个消息头并未指明正被发送的消息类型(MapMessage、TextMessage 等),而是 JMS 提供者使用的内部消息仓库中的一个条目。

 

消息属性

  消息的属性就像可以分配给一条消息的附加消息头一样。它们允许开发者添加有关消息的不透明附加信息。它们还用于暴露消息选择器在消息过滤时使用的数据。 Message 接口为读写属性提供了若干个取值函数和赋值函数方法。消息的属性可以是 String、boolean、byte、int、long、double 或 float 类型。

Enumeration<?> propertyNames = message.getPropertyNames();
while (propertyNames.hasMoreElements()) {
    String name = (String) propertyNames.nextElement();
    Object value = message.getObjectProperty(name);
    System.out.println(name + " = " + value);
}

 

消息类型

  JMS 定义了 6 种 JMS 提供者必须支持的 Message 接口类型。这 6 个消息接口是 Message 和它的 5 个子接口:TextMessage、ObjectMessage、BytesMessage、StreamMessage 和 MapMessage。

Message

  最简单的消息类型是 javax.jms.Message,它担当了其他消息类型基接口的角色。可以使用 session.createMessage() 方法创建一条不含有效负载的 JMS 消息。如果业务场景需要一个不含有效负载的简单通知,轻量级消息类型就是实现它的最有效方式。

TextMessage

  TextMessage 携带了一个 java.lang.String 对象作为有效负载。它可以用于简单的字符数据交换或者像 XML 文档这样更加复杂的字符数据的交换。

ObjectMessage

  ObjectMessage 携带了一个可序列化 Java 对象最为有效负载,可以用于 Java 对象交换。

BytesMessage

  BytesMessage 携带了一组原始类型字节流作为有效负载。

StreamMessage

  StreamMessage 携带了一个 Java 原始数据类型流(int、double、char 等)作为有效负载。

MapMessage

  MapMessage 携带了一组名/值对作为有效负载。有效负载类似于一个 java.util.Properties 对象。

posted on 2015-08-19 15:39  huey2672  阅读(910)  评论(0编辑  收藏  举报