2.4.5 JMS消息内部
就像上面提到的,JMS消息复杂部分在它的头部。有两种头部,它们都是基于相同的逻辑概念,但是有很大的不同。除了一系列标准的头部和方法,还有properties方法。poperties是基于Java类型,用来处理自定义头部。
JMS消息头部
如图2.5所示,JMS消息支持一系列标准的消息头部,并且为之提供JMS API。很多头部会自动被赋值。接下来将描述这些头部,并看看它们 是怎么被赋值。
通过send()方法自动被赋值的头部:
- JMSDestination----消息被发送到的目的地。这个对于从多个目标中接收消息的客户端有用。
- JMSDeliveryMode----JMS支持两种消息发送模式:持久化和非持久化。默认是持久化的消息。不同的模式有不同的负载,也提供不同级别的可靠性。
持久的(Persistent)----让JMS提供者持久化消息,所以当provider失败时消息不会丢失。JMS提供者必须投递每个持久化消息一次并且只有一次。也就是说,即使JMS提供者失败,消息不会丢失也不会被投递多于一次。 由于需要存储消息及提高稳定性,所以持久化消息会要求更多的开销。
非持久的(Nonpersistent)----让JMS提供者不要持久化消息。JMS对于非持久化消息最多投递一次。也就是说,如果消息投递失败,则会丢失。非持久化消息开销较小,同时稳定性也较差。
消息投递模式是设置在生产者上面的,它对该生产者生产的所有消息有效。不过,消息投递模式也可以在单独的发生某个消息时被重写。
- JMSExpiration----JMS消息的过期时间。这个头部会阻止发送一条已经过期的消息。有两种方法设置过期时间。一种是通过MessageProducer.setTimeToLive()方法,此方法设置的消息存在时间对所有由该生产者生产的消息有效;一种是通过MessageProducer.send()方法,此方法设置的消息有效时间对本次发送的消息有效。
JMSExpiration头部是通过time-to-live时间加上当前时间计算出来的。默认地,time-to-live时间是零,这意味着消息永远不会过期。如果time-to-live被明确赋值为0,效果也是一样的。
这个头部对于时间敏感的消息有用。不过要注意,虽然JMS提供者不会发送过期消息,JMS客户端自己也必须保证不处理过期消息。
- JMSMessageID----JMS提供者产生的消息唯一标识,它必须以提供者的id开头。消息id可以用在消息处理,也可以储存下来用于追踪历史信息。由于生成id会给JMS提供者带来一些开销,所以生产者可以通过MessageProducer.setDisableMessageID()方法,告诉JMS提供者,应用不需要JMSMessageID。如果JMS提供者接受请求,则消息ID会被设置为null。不过要注意,JMS也可能忽略该请求,仍然提供MessageID。
- JMSPriority----用于指明消息的重要级别。这个也是设置在消息生产者上面的,并且对该生产者生产的所有消息有效。也可以对单独的消息重写这个优先级。JMS定义了0-9十个基本的优先级。
Priorities 0-4 ----属于通常级别。
Priorities 5-9 ----属于加快级别。
JMS提供者并没有被要求实现消息顺序,不过大多数都会提供该功能。它们可能简单地先发送高优先级的消息再发
送低优先级的消息。
- JMSTimestamp----显示消息是何时从生产者发到消息提供者的。这个值使用Java标准毫秒数。就像JMSMessageID一样,生产者也可以建议JMS提供者不用提供这个值。设置的方法是MessageProducer.setDisableMessageTimestamp()。如果JMS提供者接受该建议,则这个值被设置为0.
客户端可选的头部 :
- JMSCorrelationID----用来关联当前消息和之前的消息。最常用在关联一条响应消息和它的请求消息。这个值可以是:
* 一个提供者指定的消息ID。
* 一个应用指定的字符串。
* 一个提供者本地的字节数组
由提供者指定的消息ID都会带有ID前缀,所以,应用指定的字符串不应带有ID前缀。如果一个JMS提供者支持本地
的correlation ID,那么JMS客户端可能需要对correlation ID赋值以匹配非JMS客户端,不过这个并非强制要
求。
- JMSReplyTo----用来指定一个响应发生的目标。这个值一般用在请求/响应的消息传送风格中。使用该头部的消息表明它期望得到响应,不过这并非强制要求。由客户端决定是否响应。
- JMSType----语义上的消息类型。只有很少供应商使用该头部,而且它和消息的负载类型(持久化/非持久化)无关。