剖析1條JMS消息 原 薦

前言

一個JMS消息分爲:

1.消息頭

2.屬性

3.消息體(有效負載)

1.消息頭

1.1 系統默認分配的消息頭

  • a. JMSDestination :Topic 和Queue用此屬性標識目的地,二者都是Destination類型。

            javax.jms.Message接口有對應的getJMSDestination()方法。

  • b.JMSDeliveryMode:傳送模式:

            持久化 : javax.jms.DeliveryMode.PERSISTENT

            非持久化 : javax.jms.DeliveryMode.NON_PERSISTENT

            javax.jms.MessageProducer接口,中有設置該消息頭的方法。

            JmsTemplate設置方式如下:

JmsTemplate.setDeliveryPersistent(boolean deliveryPersistent);
  • c.JMSMessageID:String類型,消息的唯一標示
  • d.JMSTimeStamp:由MessageProducer在調用send時自動,設置。long類型。用於確定發送消息和該消息被消息者實際接收的時間間隔。
  • e.JMSExpiration:設置消息的過期時間。
MessageProducer.setTimeToLive()//進行設置。

JmsTemplate.setTimeToLive(long timeToLive)

        默認不過期,javax.jms.Message.DEFAULT_TIME_TO_LIVE(該值爲0,表示永不過期)

  • f.JMSRedelivered:標示該消息將重複給消費者。如果爲true,表示該消息將被重新發送,僅在需要確認消息的模式下有效。
  • g.JMSPriority:JMS優先級,0-4普通,5-9加急,加急會比普通優先發送。

          默認優先級爲javax.jms.Message.DEFAULT_PRIORITY(即爲4)。

1.2 爲開發者分配的消息頭

  • a.JMSReplayTo:設置應答隊列,僅僅對Queue模式有用。

            JmsTemplate沒有主動設置的部分,sendAndReceive方法時會臨時生成一個隊列。

  • b.JMSCorrelationID:業務關聯ID,一般情況下用於應答,存儲上一條消息的JMSMessageID,表示 是這條消息的應答。

            MessageListenerAdapter.onMessage會進行設置。

  • c.JMSType:可選消息頭,用於標註類型和有效負載類型,非MapMessage。某些消息系統需要這個字段。

2.消息屬性

    類似附加消息頭。可以是boolean,Byte,Short,Integer,Long,float,double,Object類型

2.1應用特定的屬性(自定義數據)

一般用於消息選擇器。Message接口有對應的get,set方法。

jmsTemplate 的設置方式如下:

jmsTemplate.convertAndSend(queue, obj, new MessagePostProcessor() {

@Override

public Message postProcessMessage(Message message) throws JMSException {

for (Entry<String, String> head : appendHeaders.entrySet()) {

message.setStringProperty(head.getKey(), head.getValue());

}

return message;

}

});

2.2 JMS定義的屬性

默認以JMSX開頭,這些消息頭是可選的。

名稱

類型

由誰設置

作用

JMSXUserID

String

MQ在發送時設置

發送消息的UserId

JMSXAppID

String

MQ在發送時設置

發送消息的應用ID

JMSXDeliveryCount

int

MQ在接收時設置

消息嘗試發送的次數,第一次爲1,第二次爲2 

JMSXGroupID

String

client(調用者)端

消息所屬的分組ID

JMSXGroupSeq

int

Client(調用者)端

消息在組中的序號,第一個消息爲1,第二個消息爲2 

JMSXProducerTXID

String

MQ在接收時設置

消息生成時的事務ID

JMSXConsumerTXID

String

MQ在接收時設置

消息被消費時的事務ID

JMSXRcvTimestamp

long

MQ在接收時設置

JMS把消息發送的消費者的時間

JMSXState

int

MQ

 

假設存在一個消息倉庫,

該消息倉庫包含每個發送到消費者

的消息的獨立副本。

這些副本的存在從最初的信息開始被送時就存在

每個副本的狀態,是如下狀態其中之一:

1(等待)2(就緒)3(過期)4(保留)

因爲狀態對生成者和消費者都無用,

所以不由他們提供。

這個狀態僅僅用於在倉庫中查詢,

JMS沒有對應的API

2.3MQ特定的消息

用於支持廠商的私有特性。我在工作中沒有使用到,不做介紹。

3.消息類型

JMS提供了6個消息接口,分別是:

  • Message
  • BytesMessage,
  • MapMessage,
  • ObjectMessage(傳遞序列化後的消息),
  • StreamMessage,
  • TextMessage。

Message

若使用Message,僅僅包含消息頭和消息屬性。基本僅僅用作事件通知。廣播,警告,或者通知 中。

TextMessage

使用setText設置有效負載。getText獲取消息。

ObjectMessage

setObject方法,注意這個對象必須要序列化。

BytesMessage

原始字節流作爲有效負載

設置消息類似java.io.DataInputStream和java.io.DataOutputStream方法。

BytesMessage byteMessage=Session.createByteSession();

byteMessage.writeChar('c');

byteMessage.writeInt(10);

byteMessage.writeUTF("O my god");

StreamMessage

負載爲java原數據類型流.允許將null寫入流。讀取的順序與寫入的順序一致。

讀取時的類型轉換規則如下:

寫類型

讀可轉換的類型

boolean

boolean,String

byte

byte,short,int,long,String

short

short,int,long,String

char

char,String

long

long,String

int

int,long,String

float

float,double,String

String

String,boolean,byte,short,int,long,float,double

byte[]

byte[]

若讀取時遇到異常,嘗試重新讀取,需要調用reset方法,將讀取指針返回到開始的地方

MapMessage

    負載爲一組鍵值對.

    JMS客戶端試圖讀取,一個不存在的值時,該值視爲null。

    注意:    

    getObject方法會對不存在的映射放回null

    大多數的原始類似取值函數會返回,java.lang.NumberFormatException。

    getBoolean()方法將爲null值返回false;

    getString(),可能返回null,或者一個空字符串。

    getChar(),會拋出java.lang.NullPointerException。

爲了避免上述問題,MapMessage提供了一個itemExists()的測試方法。另外getMapNames()可以讓JMS客戶端列舉出Key。

總結

    這篇blog,基本上都是JMS消息的概念,下篇blog會介紹activemq的負載均衡的搭建,預計下週完成。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章