深入剖析一条JMS消息(消息头)

原创
2014/10/26 12:59
阅读数 4K

一个Message对象有3个部分:消息头消息属性,最后就是消息数据自身,它称为有效负载或消息体。消息能够携带重要的数据或仅仅用于系统中的事件通知。在大多数情况下,消息同时作为通知和携带数据的工具。下面我们先来说说消息头

每条JMS消息都有一组标准的消息头。每个消息头都由一组取值函数和赋值函数方法所标识,这些方法名称紧跟在术setJMS<HEADER>(),getJMS<HEADER>()之后。下面是一个Message接口的部分定义,它显示了JMS消息头使用的所有方法:

public interface Message {
    public Destination getJMSDestination() throws JMSException;
    public void setJMSDestination(Destination destination) throws JMSException;
    public int getJMSDeliveryMode() throws JMSException
    public void setJMSDeliveryMode(int deliveryMode) throws JMSException;
    public String getJMSMessageID() throws JMSException;
    public void setJMSMessageID(String id) throws JMSException;
    public long getJMSTimestamp() throws JMSException'
    public void setJMSTimestamp(long timestamp) throws JMSException;
    public long getJMSExpiration() throws JMSException;
    public void setJMSExpiration(long expiration) throws JMSException;
    public boolean getJMSRedelivered() throws JMSException;
    public void setJMSRedelivered(boolean redelivered) throws JMSException;
    public int getJMSPriority() throws JMSException;
    public void setJMSPriority(int priority) throws JMSException;
    public Destination getJMSReplyTo() throws JMSException;
    public void setJMSReplyTo(Destination replyTo) throws JMSException;
    public String getJMScorrelationID() throws JMSException;
    public void setJMSCorrelationID(String correlationID) throws JMSException;
    public byte[] getJMSCorrelationIDAsBytes() throws JMSException;
    public void setJMSCorrelationIDAsBytes(byte[] correlationID) throws JMSException;
    public String getJMSType() throws JMSException;
    public void setJMSType(String type) throws JMSException;
}

JMS消息头可以分为大类自动分配的消息头开发者分配的消息头


1. 自动分配的消息头

大多数JMS消息头是自动分配的,在传送消息时,消息头的值由JMS提供者来设置,因此开发者使用setJMS<HEADER>()方法分配的值就被忽略了。换句话说,对于大多数自动分配的消息头来说,使用赋值函数方法显然是徒劳的。不过,这并非意味着开发者无法控制这些消息头的值。一些自动分配的消息头可以在创建Session和MessageProducer(也就是TopicPublisher)时,由开发者通过编程方式来设置。这样的例子有JMSDeliveryModeJMSPriority消息头,它们在随后的消息头定义中会有所解释。

JMSDeliveryMode

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

int deliverymode = message.getJMSDeliveryMode();
if(deliverymode = javax.jms.DeliveryMode.PERSISTENT) {        //持久化
    ......
}else {    //DeliveryMode.NON_PERSISTENT    非持久化
    ......
}

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

//在消息生产者上设置JMS传送模式
TopicPublisher topicPublisher = topicSession.createPublisher(topic);
topicPubiisher.setDeliveryMode(DeliverMode.NON_PERSISTENT);

JMSMessageID

JMSMessageID是一个String类型值,它唯一地标识了一条消息。

JMSTimestamp

JMSTimestamp由MessageProducer在调用send()操作时自动设置。它包含的是JMS提供者接收消息的时间,而不是该消息实际传送的时间。这条消息头用于确定发送消息和它被消费者实际接收的时间间隔。时间戳是一个以毫秒来计算的long类型时间值(自1970年1月1日算起)。

JMSExpiration

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

long timeToLive = message.getJMSExpiration();

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

TopicPublisher topicPublisher = topicSession.createPublisher(topic);
//将生存时间设置为1小时(1000毫秒 *60 *60)
topicPublisher .setTimeToLive(3600000);

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

JMSRedelivered

JMSRedelivered消息头表示该消息将被重新传送给消费者如果该消息被重新传送,JMSRedelivered消息头就为true,否则为false。如果一个消费者未能确认先前传送的消息,或者JMS提供者并不确定消费者是否已经接收到该消息时,就可以将这条消息标记为重新传送。更多细节,我们后面再讨论。

JMSPriority

在传送一条消息时,消息生产者能够为该消息分配一个优先级。消息优先级共有两类:0~4级是普通优先级5~9级则是加急优先级。消息服务器能够利用一条消息的优先级,按优先次序将该消息传送给消息者:加急优先级的消息要比普通优先级的消息优先传送:

int priority = message.getJMSPriority();

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

TopicPublisher topicPublisher = TopicSession.createPublisher(someTopic);
topicPublisher.setPriority(9);

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


2. 开发者分配的消息头

JMSReplyTo

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

JMSCorrelationID

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

JMSType

JMSType是由JMS客户端设置的一个可选消息头。它的主要作用是标识消息结构和有效负载的类型。请注意,这个消息头并未指明被发送的消息类型(MapMessge,TextMessage等),而是JMS提供者使用的内部消息仓库中的一个条目。一些MOM系统(比如IBM的WebSphere MO)将消息体视为连续的字节流。这些系统通常为应用程序提供了一种消息类型,作为标记消息体的一种简单方式。有些非JMS的客户端需要使用某种类型的信息来处理有效负载。因此,在和这类非JMS客户端进行消息交换时,消息类型会非常有用。



展开阅读全文
JMS
打赏
0
3 收藏
分享
加载中
更多评论
打赏
0 评论
3 收藏
0
分享
返回顶部
顶部