Java訊息佇列--JMS概述
1、什麼是JMS
JMS即Java訊息服務(Java Message Service)應用程式介面,是一個Java平臺中關於面向訊息中介軟體(MOM)的API,用於在兩個應用程式之間,或分散式系統中傳送訊息,進行非同步通訊。Java訊息服務是一個與具體平臺無關的API,絕大多數MOM提供商都對JMS提供支援(百度百科給出的概述)。我們可以簡單的理解:兩個應用程式之間需要進行通訊,我們使用一個JMS服務,進行中間的轉發,通過JMS 的使用,我們可以解除兩個程式之間的耦合。
2、JMS的優勢
-
Asynchronous(非同步)
JMS is asynchronous by default. So to receive a message, the client is not required to send the request. The message will arrive automatically to the client as they become available.(JMS 原本就是一個非同步的訊息服務,客戶端獲取訊息的時候,不需要主動傳送請求,訊息會自動傳送給可用的客戶端)
-
Reliable(可靠)
JMS provides the facility of assurance that the message will delivered once and only once. You know that duplicate messages create problems. JMS helps you avoiding such problems.(JMS保證訊息只會遞送一次。大家都遇到過重複建立訊息問題,而JMS能幫你避免該問題。)
3、JMS的訊息模型
JMS具有兩種通訊模式:
1、Point-to-Point Messaging Domain (點對點)
2、Publish/Subscribe Messaging Domain (釋出/訂閱模式)
在JMS API出現之前,大部分產品使用“點對點”和“釋出/訂閱”中的任一方式來進行訊息通訊。JMS定義了這兩種訊息傳送模型的規範,它們相互獨立。任何JMS的提供者可以實現其中的一種或兩種模型,這是它們自己的選擇。JMS規範提供了通用介面保證我們基於JMS API編寫的程式適用於任何一種模型。
(1)、Point-to-Point Messaging Domain(點對點通訊模型)
a、模式圖:
b、涉及到的概念:
在點對點通訊模式中,應用程式由訊息佇列,傳送方,接收方組成。每個訊息都被髮送到一個特定的佇列,接收者從佇列中獲取訊息。佇列保留著訊息,直到他們被消費或超時。
c、特點:
-
-
- 每個訊息只要一個消費者
- 傳送者和接收者在時間上是沒有時間的約束,也就是說傳送者在傳送完訊息之後,不管接收者有沒有接受訊息,都不會影響傳送方傳送訊息到訊息佇列中。
- 傳送方不管是否在傳送訊息,接收方都可以從訊息佇列中去到訊息(The receiver can fetch message whether it is running or not when the sender sends the message)
- 接收方在接收完訊息之後,需要向訊息佇列應答成功
-
(2)、Publish/Subscribe Messaging Domain(釋出/訂閱通訊模型)
a、模式圖:
b、涉及到的概念:
在釋出/訂閱訊息模型中,釋出者釋出一個訊息,該訊息通過topic傳遞給所有的客戶端。該模式下,釋出者與訂閱者都是匿名的,即釋出者與訂閱者都不知道對方是誰。並且可以動態的釋出與訂閱Topic。Topic主要用於儲存和傳遞訊息,且會一直儲存訊息直到訊息被傳遞給客戶端。
c、特點:
-
-
- 一個訊息可以傳遞個多個訂閱者(即:一個訊息可以有多個接受方)
- 釋出者與訂閱者具有時間約束,針對某個主題(Topic)的訂閱者,它必須建立一個訂閱者之後,才能消費釋出者的訊息,而且為了消費訊息,訂閱者必須保持執行的狀態。
- 為了緩和這樣嚴格的時間相關性,JMS允許訂閱者建立一個可持久化的訂閱。這樣,即使訂閱者沒有被啟用(執行),它也能接收到釋出者的訊息。
-
4、JMS接收訊息
在JMS中,訊息的產生和訊息是非同步的。對於消費來說,JMS的訊息者可以通過兩種方式來消費訊息。
(1)、同步(Synchronous)
在同步消費資訊模式模式中,訂閱者/接收方通過呼叫receive()方法來接收訊息。在receive()方法中,執行緒會阻塞直到訊息到達或者到指定時間後訊息仍未到達。
(2)、非同步(Asynchronous)
使用非同步方式接收訊息的話,訊息訂閱者需註冊一個訊息監聽者,類似於事件監聽器,只要訊息到達,JMS服務提供者會通過呼叫監聽器的onMessage()遞送訊息。
5、JMS程式設計模型
- 管理物件(Administered objects)-連線工廠(Connection Factories)和目的地(Destination)
- 連線物件(Connections)
- 會話(Sessions)
- 訊息生產者(Message Producers)
- 訊息消費者(Message Consumers)
- 訊息監聽者(Message Listeners)
(1)、Connection Factories
建立Connection物件的工廠,針對兩種不同的jms訊息模型,分別有QueueConnectionFactory和TopicConnectionFactory兩種。可以通過JNDI來查詢ConnectionFactory物件。客戶端使用一個連線工廠物件連線到JMS服務提供者,它建立了JMS服務提供者和客戶端之間的連線。JMS客戶端(如傳送者或接受者)會在JNDI名字空間中搜索並獲取該連線。使用該連線,客戶端能夠與目的地通訊,往佇列或話題傳送/接收訊息。
QueueConnectionFactory queueConnFactory = (QueueConnectionFactory) initialCtx.lookup ("primaryQCF"); Queue purchaseQueue = (Queue) initialCtx.lookup ("Purchase_Queue"); Queue returnQueue = (Queue) initialCtx.lookup ("Return_Queue");
(2)、Destination
目的地指明訊息被髮送的目的地以及客戶端接收訊息的來源。JMS使用兩種目的地,佇列和話題。如下程式碼指定了一個佇列和話題:
建立一個佇列Session:
QueueSession ses = con.createQueueSession (false, Session.AUTO_ACKNOWLEDGE); //get the Queue object Queue t = (Queue) ctx.lookup ("myQueue"); //create QueueReceiver QueueReceiver receiver = ses.createReceiver(t);
(3)、Connection
Connection表示在客戶端和JMS系統之間建立的連結(對TCP/IP socket的包裝)。Connection可以產生一個或多個Session。跟ConnectionFactory一樣,Connection也有兩種型別:QueueConnection和TopicConnection。
連線物件封裝了與JMS提供者之間的虛擬連線,如果我們有一個ConnectionFactory物件,可以使用它來建立一個連線。
Connection connection = connectionFactory.createConnection();
(4)、Session
Session 是我們對訊息進行操作的介面,可以通過session建立生產者、消費者、訊息等。Session 提供了事務的功能,如果需要使用session傳送/接收多個訊息時,可以將這些傳送/接收動作放到一個事務中。
我們可以在連線建立完成之後建立session:
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
這裡面提供了引數兩個引數,第一個引數是是否支援事務,第二個是事務的型別
(5)、Producter
訊息生產者由Session建立,用於往目的地傳送訊息。生產者實現MessageProducer介面,我們可以為目的地、佇列或話題建立生產者;
MessageProducer producer = session.createProducer(dest); MessageProducer producer = session.createProducer(queue); MessageProducer producer = session.createProducer(topic);
6)、Consumer
訊息消費者由Session建立,用於接收被髮送到Destination的訊息。
MessageConsumer consumer = session.createConsumer(dest); MessageConsumer consumer = session.createConsumer(queue); MessageConsumer consumer = session.createConsumer(topic);
(7)、MessageListener
訊息監聽器。如果註冊了訊息監聽器,一旦訊息到達,將自動呼叫監聽器的onMessage方法。EJB中的MDB(Message-Driven Bean)就是一種MessageListener。