1. 程式人生 > >JAVA訊息服務JMS規範及原理詳解

JAVA訊息服務JMS規範及原理詳解

一、簡介

JMS即Java訊息服務(Java Message Service)應用程式介面,是一個Java平臺中關於面向訊息中介軟體(MOM)的API,用於在兩個應用程式之間,或分散式系統中傳送訊息,進行非同步通訊。Java訊息服務是一個與具體平臺無關的API,絕大多數MOM提供商都對JMS提供支援。

JMS允許應用程式元件基於JavaEE平臺建立、傳送、接收和讀取訊息。它使分散式通訊耦合度更低,訊息服務更加可靠以及非同步性。

二、常用術語介紹

  在提到JMS時,我們通常會說到一些術語,解釋如下:

  1. 訊息中介軟體(JMS Provider) : 指提供了對JMS協議的第三方元件,比如ActiveMQ就是一個訊息中介軟體,另外比較知名的還有KFA, Rabbit MQ等。
  2. 訊息模式:分為點對點(Point to Point,即P2P)和釋出/訂閱(Pub/Sub),對應的資料結構分別是佇列(Queue)和主題(Topic)
  3. 訊息(Message): 通訊內容的載體,其結構主要分為訊息頭,屬性和訊息體,並且根據儲存結構的不同分為好幾種,後面會詳細提到。
  4. 訊息生產者:產生訊息的一方,在P2P模式下,指訊息傳送者(Sender),在P/S模式下指訊息釋出者(Publisher)
  5. 訊息消費者:接收訊息的一方,對應於兩種模式分別是訊息接收者(Receiver)和訊息訂閱者(Subscriber)                          

三、JMS基本概念及原理詳解

1、基本概念


  JMS是java的訊息服務,JMS的客戶端之間可以通過JMS服務進行非同步的訊息傳輸。

2、體系架構

  JMS由以下元素組成。

  1.JMS提供者 
  連接面向訊息中介軟體的,JMS介面的一個實現。提供者可以是Java平臺的JMS實現,也可以是非Java平臺的面向訊息中介軟體的介面卡。

  2.JMS客戶 
  生產或消費訊息的基於Java的應用程式或物件。

  3.JMS生產者 
  建立併發送訊息的JMS客戶。

  4.JMS消費者 
  接收訊息的JMS客戶。

  5.JMS訊息 
  包括可以在JMS客戶之間傳遞的資料的物件

  6.JMS佇列 
  一個容納那些被髮送的等待閱讀的訊息的區域。佇列暗示,這些訊息將按照順序傳送。一旦一個訊息被閱讀,該訊息將被從佇列中移走。

  7.JMS主題 
  一種支援傳送訊息給多個訂閱者的機制。


3、JMS訊息模型(即點對點和釋出訂閱模型)

    1、Point-to-Point(P2P)

    2、Publish/Subscribe(Pub/Sub)


4、P2P
  1、P2P模式圖效果
      
  2、涉及到的概念

    2.1、訊息佇列(Queue)
    2.2、提供者(Sender)
    2.3、消費者(Receiver)
    2.4、每個訊息都被髮送到一個特定的佇列,接收者從佇列中獲取訊息。佇列保留著訊息,直到他們被消費或超時。

  3、P2P的特點    

    3.1、每個訊息只有一個消費者(Consumer)(即一旦被消費,訊息就不再在訊息佇列中)
    3.2、提供者和消費者之間在時間上沒有依賴性,也就是說當提供者傳送了訊息之後,不管消費者有沒有正在執行,它不會影響到訊息被髮送到佇列
    3.3、每條訊息僅會傳送給一個消費者。可能會有多個消費者在一個佇列中偵聽,但是每個佇列中的訊息只能被佇列中的一個消費者所消費。
    3.4、訊息存在先後順序。一個佇列會按照訊息伺服器將訊息放入佇列中的順序,把它們傳送給消費者。當已被消費時,就會從佇列頭部將它們刪除(除非使用了訊息優先順序)。
    3.5、消費者在成功接收訊息之後需向佇列應答成功
    PS:如果你希望傳送的每個訊息都應該被成功處理的話,那麼你需要P2P模式。


5、Pub/Sub(釋出/訂閱模式)
  
  1、Pub/Sub模式效果圖
  2、涉及到的概念

    2.1、主題(Topic)
    2.2、釋出者(Publisher)
    2.3、訂閱者(Subscriber)

    PS:客戶端將訊息傳送到主題。多個釋出者將訊息傳送到Topic,系統將這些訊息傳遞給多個訂閱者。
  
  3、Pub/Sub(釋出/訂閱模式)的特點

    3.1、每個訊息可以有多個消費者
    3.2、釋出者和訂閱者之間有時間上的依賴性。針對某個主題的訂閱者,它必須建立一個訂閱者之後,才能消費釋出者的訊息,而且為了消費訊息,訂閱者必須保持執行的狀態。
    3.3、為了緩和這樣嚴格的時間相關性,JMS允許訂閱者建立一個可持久化的訂閱。這樣,即使訂閱者沒有被啟用(執行),它也能接收到釋出者的訊息。
    3.4、每條訊息都會傳送給稱為訂閱者的多個訊息消費者。訂閱者有許多型別,包括持久型、非持久型和動態型。
    3.5、釋出者通常不會知道、也意識不到哪一個訂閱者正在接收主題訊息。
    3.6、訊息被推送給消費者,這意味著訊息會傳送給消費者,而無須請求。

    PS:如果你希望傳送的訊息可以不被做任何處理、或者被一個訊息者處理、或者可以被多個消費者處理的話,那麼可以採用Pub/Sub模型


6、關於訊息的消費
  在JMS中,訊息的產生和訊息是非同步的。對於消費來說,JMS的訊息者可以通過兩種方式來消費訊息。
  

  6.1、同步

    訂閱者或消費者呼叫receive方法來接收訊息,receive方法在能夠接收到訊息之前(或超時之前)將一直阻塞

  6.2、非同步

    訂閱者或消費者可以註冊為一個訊息監聽器。當訊息到達之後,系統自動呼叫監聽器的onMessage方法。

7、JMS應用程式介面

  7.1、ConnectionFactory 介面(連線工廠)
    建立Connection物件的工廠,根據訊息型別的不同,使用者將使用佇列連線工廠,或者主題連線工廠分,
    別有QueueConnectionFactory和TopicConnectionFactory兩種。可以通過JNDI來查詢ConnectionFactory物件。
  
  7.2、Destination 介面(目標)
    Destination是一個包裝了訊息目標識別符號的被管物件,訊息目標是指訊息釋出和接收的地點,或者是佇列,或者是主題。
    是訊息生產者的訊息傳送目標或者說訊息消費者的訊息來源。對於訊息生產者來說,它的Destination是某個佇列(Queue)或某個主題(Topic);
    對於訊息消費者來說,它的Destination也是某個佇列或主題(即訊息來源)。
    所以,Destination實際上就是兩種型別的物件:Queue、Topic可以通過JNDI來查詢Destination。

  7.3、Connection 介面(連線)
    Connection表示在客戶端和JMS系統之間建立的連結(對TCP/IP socket的包裝)。
    Connection可以產生一個或多個Session。跟ConnectionFactory一樣,Connection也有兩種型別:QueueConnection和TopicConnection。

  7.4、Session 介面(會話)
    Session是我們操作訊息的介面。表示一個單執行緒的上下文,用於傳送和接收訊息。
    由於會話是單執行緒的,所以訊息是連續的,就是說訊息是按照發送的順序一個一個接收的。
    可以通過session建立生產者、消費者、訊息等。Session提供了事務的功能。當我們需要使用session傳送/接收多個訊息時,可以將這些傳送/接收動作放到一個事務中。
    同樣,也分QueueSession和TopicSession。

  7.5、MessageProducer 介面(訊息的生產者)
    訊息生產者由Session建立,並用於將訊息傳送到Destination。消費者可以同步地(阻塞模式),或非同步(非阻塞)接收佇列和主題型別的訊息。
    同樣,訊息生產者分兩種型別:QueueSender和TopicPublisher。可以呼叫訊息生產者的方法(send或publish方法)傳送訊息。

  7.6、MessageConsumer 介面(訊息消費者)
    訊息消費者由Session建立,用於接收被髮送到Destination的訊息。兩種型別:QueueReceiver和TopicSubscriber。
    可分別通過session的createReceiver(Queue)或createSubscriber(Topic)來建立。
    當然,也可以session的creatDurableSubscriber方法來建立持久化的訂閱者。

  7.7、Message 介面(訊息)
    是在消費者和生產者之間傳送的物件,也就是說從一個應用程式創送到另一個應用程式。一個訊息有三個主要部分:
    1、訊息頭(必須):包含用於識別和為訊息尋找路由的操作設定。
    2、一組訊息屬性(可選):包含額外的屬性,支援其他提供者和使用者的相容。可以建立定製的欄位和過濾器(訊息選擇器)。
    3、一個訊息體(可選):允許使用者建立五種型別的訊息(文字訊息,對映訊息,位元組訊息,流訊息和物件訊息)。訊息介面非常靈活,並提供了許多方式來定製訊息的內容。

    訊息介面非常靈活,並提供了許多方式來定製訊息的內容。

  7.8、MessageListener
    訊息監聽器。如果註冊了訊息監聽器,一旦訊息到達,將自動呼叫監聽器的onMessage方法。
    EJB中的MDB(Message-Driven Bean)就是一種MessageListener。

四、JMS提供者實現

  要使用Java訊息服務,你必須要有一個JMS提供者,管理會話和佇列。現在既有開源的提供者也有專有的提供者。
  開源的提供者包括:Apache ActiveMQ、Kafka、WebMethods、阿里的RocketMQ等