一、前言
從本文起依次詳細介紹JMS中的一些重要的概念,主要參考了官方的JMS1.1的文檔,該文檔很老了,是02年的,那年,JAVA還沒有被Oracle收購。。本文主要介紹Message及其相關概念,由於官方文檔講解得很詳細,所以這個也基本上就是照搬了,只是由於時間關系,不能完全翻譯了,所以本文只說重點。
二、Message的組成
上一次面試的時候,面試官問過我這個問題,但當時完全是一頭霧水,用過ActiveMQ好幾次了,但每次都是下個軟件,起個服務,然后就在網上找一段模板代碼配置好,能收到消息就OK,從來沒有去關注過。現在想來,自己之所以技術一直沒有得到提高,和自己學技術的方式是有關系的,知其然,而不知其所以然。
進入正題,Message主要由三部分組成,分別是Header,Properties和Body, 解釋如下:
Header: 消息頭,所有類型的這部分格式都是一樣的
Properties: 屬性,按類型可以分為應用設置的屬性,標准屬性和消息中間件定義的屬性
Body: 消息正文,指我們具體需要消息傳輸的內容。
為了便於說明,下面用一個表格來描述Header中的各個屬性
| 序號 | 屬性名稱 | 說明 | 設置者 |
|
1 |
JMSDestination |
消息發送的目的地,是一個Topic或Queue | send |
|
2 |
JMSDeliveryMode |
消息的發送模式,分為NON_PERSISTENT和PERSISTENT,即持久化的和非持久化的 | send |
|
3 |
JMSMessageID |
消息ID,需要以ID:開頭 | send |
|
4 |
JMSTimestamp |
消息發送時的時間,也可以理解為調用send()方法時的時間,而不是該消息發送完成的時間 | send |
|
5 |
JMSCorrelationID |
關聯的消息ID,這個通常用在需要回傳消息的時候 | client |
|
6 |
JMSReplyTo |
消息回復的目的地,其值為一個Topic或Queue, 這個由發送者設置,但是接收者可以決定是否響應 | client |
|
7 |
JMSRedelivered |
消息是否重復發送過,如果該消息之前發送過,那么這個屬性的值需要被設置為true, 客戶端可以根據這個屬性的值來 確認這個消息是否重復發送過,以避免重復處理。 |
Provider |
|
8 |
JMSType |
由消息發送者設置的個消息類型,代表消息的結構,有的消息中間件可能會用到這個,但這個並不是是批消息的種類,比如 TextMessage之類的 |
client |
|
9 |
JMSExpiration |
消息的過期時間,以毫秒為單位,根據定義,它應該是timeToLive的值再加上發送時的GMT時間,也就是說這個指的是過期 時間,而不是有效期 |
send |
|
10 |
JMSPriority |
消息的優先級,0-4為普通的優化級,而5-9為高優先級,通常情況下,高優化級的消息需要優先發送 | send |
從上表中我們可以看到,系統提供的標准頭信息一共有10個屬性,其中有6個是由send方法在調用時設置的,有三個是由客戶端設置的,還有一個是由消息中間件設置的。
需要注意的是,這里的client不是指消費者,而是指使用JMS的客戶端,即開發者所寫的應用程序,即在生產消息時,這三個屬性是可以由應用程序來設定的,而其它的header要么由消息中間件設置,要么由發送方法來決定,開發者即使設置了,也是無效的。
為了驗證我們的猜測,個人做了個測試,結果如下:

以上截圖只顯示了關鍵的設置代碼和消費者獲取到消息之后的打印結果,從中可以得到以下結論:
1)只有JmsType, ReplyTo和CorrelationId可以顯示設置,其它都無效
2)優先級和有效期可以由生產者來設置
3)Expiration的值等於Timestemp的時間加上timeToLive的值,是一個絕對時間。
基於以上結論,對於大多數屬性來說,我們知道其表示的意義即可,因為我們無法改變這些值的設置。
