前言
一個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的負載均衡的搭建,預計下週完成。