1. 程式人生 > >Java訊息佇列--JMS概述

Java訊息佇列--JMS概述

1、什麼是JMS

    JMS即Java訊息服務(Java Message Service)應用程式介面,是一個Java平臺中關於面向訊息中介軟體(MOM)的API,用於在兩個應用程式之間,或分散式系統中傳送訊息,進行非同步通訊。Java訊息服務是一個與具體平臺無關的API,絕大多數MOM提供商都對JMS提供支援(百度百科給出的概述)。我們可以簡單的理解:兩個應用程式之間需要進行通訊,我們使用一個JMS服務,進行中間的轉發,通過JMS 的使用,我們可以解除兩個程式之間的耦合。

2、JMS的優勢  

  1. 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 原本就是一個非同步的訊息服務,客戶端獲取訊息的時候,不需要主動傳送請求,訊息會自動傳送給可用的客戶端)

  2. 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程式設計模型 

  1. 管理物件(Administered objects)-連線工廠(Connection Factories)和目的地(Destination)
  2. 連線物件(Connections)
  3. 會話(Sessions)
  4. 訊息生產者(Message Producers)
  5. 訊息消費者(Message Consumers)
  6. 訊息監聽者(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。