MQ消息隊列(2)—— Java消息服務接口(JMS)


一、理解JMS

  1、什么是JMS?

        JMSJava消息服務(Java Message Service)應用程序接口,API是一個消息服務的標准或者說是規范,允許應用程序組件基於JavaEE平台創建、發送、接收讀取消息。它使分布式通信耦合度更低,消息服務更加可靠以及異步性。

  我們可以簡單的理解兩個應用程序之間需要進行通信,我們使用一個JMS服務,進行中間的轉發,通過JMS 的使用,我們可以解除兩個程序之間的耦合。

       JMS不是消息隊列,更不是某種消息隊列協議。JMS是Java消息服務接口,是一套規范的JAVA API 接口

  1)這套規范接口由SUN提出,並在2002年發布JMS規范的Version 1.1版本。

  2)JMS和消息中間件廠商無關,既然是一套接口規范,就代表這它需要各個廠商進行實現。

  3)大部分消息中間件產品都支持JMS 接口規范,eg: 可以使用JMS API來連接Stomp協議的產品(例如ActiveMQ)。

     就像您可以使用JDBC API來連接ORACLE或者MYSQL一樣。

 

2、JMS的消息模型

 JMS具有兩種通信模式:點對點發布/訂閱模式

 

3、JMS中消息的產生和消費

 在JMS中,消息的產生和消息是異步的。對於消費來說,JMS的消息者可以通過兩種方式來消費消息。 
○ 同步 :訂閱者或接收者調用receive方法來接收消息,receive方法在能夠接收到消息之前(或超時之前)將一直阻塞 
○ 異步 :訂閱者或接收者可以注冊為一個消息監聽器。當消息到達之后,系統自動調用監聽器的onMessage方法。

 

4、對象模型

(1) ConnectionFactory
創建Connection對象的工廠,針對兩種不同的jms消息模型,分別有QueueConnectionFactoryTopicConnectionFactory兩種。可以通過JNDI來查找ConnectionFactory對象。

(2) Destination
Destination,即 消息生產者的 消息發送目標,或者說 消息消費者的 消息來源

對於消息生產者來說,它的Destination是某個隊列(Queue)或某個主題(Topic);

對於消息消費者來說,它的Destination也是某個隊列或主題(即消息來源)。

所以,Destination實際上就是兩種類型的對象:Queue、Topic。可以通過JNDI來查找Destination。

 

(3) Connection
Connection表示在客戶端和JMS系統之間建立的鏈接(對TCP/IP socket的包裝)。

Connection可以產生一個或多個Session。

跟ConnectionFactory一樣,Connection也有兩種類型:QueueConnectionTopicConnection

 

(4) Session
Session是我們操作消息的接口。可以通過session創建生產者消費者消息等。

Session提供了事務的功能。

當我們需要使用session發送/接收多個消息時,可以將這些發送/接收動作放到一個事務中。

同樣,也分QueueSessionTopicSession

 

(5) 消息的生產者
消息生產者由Session創建,並用於將消息發送到Destination。

同樣,消息生產者分兩種類型:QueueSenderTopicPublisher

可以調用消息生產者的方法(send或publish方法)發送消息。

(6) 消息消費者
消息消費者由Session創建,用於接收被發送到Destination的消息。

兩種類型:QueueReceiverTopicSubscriber

可分別通過session的createReceiver(Queue)或createSubscriber(Topic)來創建。

當然,也可以session的creatDurableSubscriber方法來創建持久化的訂閱者。

 

(7) MessageListener
消息監聽器。如果注冊了消息監聽器,一旦消息到達,將自動調用監聽器的onMessage方法

EJB中的MDB(Message-Driven Bean)就是一種MessageListener。

 

 5、消息的組成

 Message主要由三部分組成,分別是Header,PropertiesBody, 解釋如下:

  1. Header: 消息頭,所有類型的這部分格式都是一樣的
  2. Properties: 屬性,按類型可以分為 應用設置的屬性 , 標准屬性 和 消息中間件定義的屬性
  3. Body: 消息正文,指我們具體需要消息傳輸的內容。

消息頭

序號 屬性名稱 說明 設置者

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

消息屬性

       消息屬性的主要作用是可以對頭信息進行一個額外的補充,畢竟消息頭信息:一是有限,二是很多不能由應用程序設定。

  通常,消息屬性可以用在消息選擇器的表達式里,結合起來實現對消息的過濾。

  消息屬性的值只能是基本的類型,或者這些基本類型對應的包裝類型。也就是說,不能將一個自定義的對象作為屬性值。

  通常情況下,如果能夠放在body里的內容,就不必放在消息屬性里。

 消息體

       為了適應不同場景下的消息,提高消息存儲的靈活性,JMS定義了幾種具體類型的消息,不同的子類型的消息體也不一樣。

  需要注意的是,Message接口並沒有提供一個統一的getBody之類的方法。

消息子接口定義如下:

1)TextMessage: 最簡單的消息接口,用於發送文本類的消息,設置/獲取其body的方法定義如下setText()/getText().


2)StreamMessage: 流式消息接口,里面定義了一系列的對基本類型的set/get方法,

           消息發送者可以通過這些方法寫入基本類型的數據,

          消息接收者需要按發送者的寫入順序來讀取相應的數據。


3)MapMessage:把消息內容存儲在Map里,本接口定義了一系列對基本類型的的set/get方法,

                                與StreamMessage不同的是,每個值都對應了一個相應的key,

                                所以消息接收者不必按順序去讀取數據。

4)ObjectMessage: 將對象作為消息的接口,提供了一個set/get 對象的方法,需要注意的是只能設置一個對象,這個對象可以是一個Collection,但必須是序列化的
5)BytesMessage: 以字節的形式來傳遞消息的接口,除了提供了對基本類型的set/get,還提供了按字節方式進行set/get。 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM