JMS(Java消息服務)入門教程【一】

来源:http://www.cnblogs.com/chenpi/archive/2016/06/06/5559349.html
-Advertisement-
Play Games

Java消息服務指的是兩個應用程式之間進行非同步通信的API,它為標準消息協議和消息服務提供了一組通用介面,包括創建、發送、讀取消息等,用於支持JAVA應用程式開發。在J2EE中,當兩個應用程式使用JMS進行通信時,它們之間並不是直接相連的,而是通過一個共同的消息收發服務連接起來,可以達到解耦的效果, ...


  Java消息服務指的是兩個應用程式之間進行非同步通信的API,它為標準消息協議和消息服務提供了一組通用介面,包括創建、發送、讀取消息等,用於支持JAVA應用程式開發。在J2EE中,當兩個應用程式使用JMS進行通信時,它們之間並不是直接相連的,而是通過一個共同的消息收發服務連接起來,可以達到解耦的效果,我們將會在接下來的教程中詳細介紹。

本文目錄:

  1. 為什麼需要JMS
  2. JMS的優勢
  3. JMS消息傳送模型
  4. JMS消息接收
  5. JMS編程介面
  6. JMS消息結構

為什麼需要JMS

  在JAVA中,如果兩個應用程式之間對各自都不瞭解,甚至這兩個程式可能部署在不同的大洲上,那麼它們之間如何發送消息呢?舉個例子,一個應用程式A部署在印度,另一個應用程式部署在美國,然後每當A觸發某件事後,B想從A獲取一些更新信息。當然,也有可能不止一個B對A的更新信息感興趣,可能會有N個類似B的應用程式想從A中獲取更新的信息。

  在這種情況下,JAVA提供了最佳的解決方案-JMS,完美解決了上面討論的問題。

  JMS同樣適用於基於事件的應用程式,如聊天服務,它需要一種發佈事件機制向所有與伺服器連接的客戶端發送消息。JMS與RMI不同,發送消息的時候,接收者不需要線上。伺服器發送了消息,然後就不管了;等到客戶端上線的時候,能保證接收到伺服器發送的消息。這是一個很強大的解決方案,能處理當今世界很多普遍問題。

JMS的優勢

非同步

  JMS天生就是非同步的,客戶端獲取消息的時候,不需要主動發送請求,消息會自動發送給可用的客戶端。

可靠

  JMS保證消息只會遞送一次。大家都遇到過重覆創建消息問題,而JMS能幫你避免該問題。

JMS消息傳送模型

  在JMS API出現之前,大部分產品使用“點對點”和“發佈/訂閱”中的任一方式來進行消息通訊。JMS定義了這兩種消息發送模型的規範,它們相互獨立。任何JMS的提供者可以實現其中的一種或兩種模型,這是它們自己的選擇。JMS規範提供了通用介面保證我們基於JMS API編寫的程式適用於任何一種模型。

  讓我們更加詳細的看下這兩種消息傳送模型:

點對點消息傳送模型

  在點對點消息傳送模型中,應用程式由消息隊列,發送者,接收者組成。每一個消息發送給一個特殊的消息隊列,該隊列保存了所有發送給它的消息(除了被接收者消費掉的和過期的消息)。點對點消息模型有一些特性,如下:

  • 每個消息只有一個接收者;
  • 消息發送者和接收者並沒有時間依賴性;
  • 當消息發送者發送消息的時候,無論接收者程式在不在運行,都能獲取到消息;
  • 當接收者收到消息的時候,會發送確認收到通知(acknowledgement)。

發佈/訂閱消息傳遞模型

  在發佈/訂閱消息模型中,發佈者發佈一個消息,該消息通過topic傳遞給所有的客戶端。在這種模型中,發佈者和訂閱者彼此不知道對方,是匿名的且可以動態發佈和訂閱topic。topic主要用於保存和傳遞消息,且會一直保存消息直到消息被傳遞給客戶端。

發佈/訂閱消息模型特性如下:

  • 一個消息可以傳遞給多個訂閱者
  • 發佈者和訂閱者有時間依賴性,只有當客戶端創建訂閱後才能接受消息,且訂閱者需一直保持活動狀態以接收消息。
  • 為了緩和這樣嚴格的時間相關性,JMS允許訂閱者創建一個可持久化的訂閱。這樣,即使訂閱者沒有被激活(運行),它也能接收到發佈者的消息。

接收消息

  在JMS中,消息的接收可以使用以下兩種方式:

同步

  使用同步方式接收消息的話,消息訂閱者調用receive()方法。在receive()中,消息未到達或在到達指定時間之前,方法會阻塞,直到消息可用。

非同步

  使用非同步方式接收消息的話,消息訂閱者需註冊一個消息監聽者,類似於事件監聽器,只要消息到達,JMS服務提供者會通過調用監聽器的onMessage()遞送消息。

JMS編程介面

  JMS應用程式由如下基本模塊組成:

  1. 管理對象(Administered objects)-連接工廠(Connection Factories)和目的地(Destination)
  2. 連接對象(Connections)
  3. 會話(Sessions)
  4. 消息生產者(Message Producers)
  5. 消息消費者(Message Consumers)
  6. 消息監聽者(Message Listeners)

JMS管理對象

管理對象(Administered objects)是預先配置的JMS對象,由系統管理員為使用JMS的客戶端創建,主要有兩個被管理的對象:

  • 連接工廠(ConnectionFactory)
  • 目的地(Destination)

這兩個管理對象由JMS系統管理員通過使用Application Server管理控制台創建,存儲在應用程式伺服器的JNDI名字空間或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");

目的地(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); 

創建一個話題Session

TopicSession ses = con.createTopicSession (false, Session.AUTO_ACKNOWLEDGE); // get the Topic object  
Topic t = (Topic) ctx.lookup ("myTopic");  //create TopicSubscriber  
TopicSubscriber receiver = ses.createSubscriber(t);  

JMS連接

連接對象封裝了與JMS提供者之間的虛擬連接,如果我們有一個ConnectionFactory對象,可以使用它來創建一個連接。

Connection connection = connectionFactory.createConnection();

創建完連接後,需要在程式使用結束後關閉它:

connection.close();

JMS 會話(Session)

Session是一個單線程上下文,用於生產和消費消息,可以創建出消息生產者和消息消費者。

Session對象實現了Session介面,在創建完連接後,我們可以使用它創建Session。

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

JMS消息生產者

消息生產者由Session創建,用於往目的地發送消息。生產者實現MessageProducer介面,我們可以為目的地、隊列或話題創建生產者;

MessageProducer producer = session.createProducer(dest);
MessageProducer producer = session.createProducer(queue);
MessageProducer producer = session.createProducer(topic);

創建完消息生產者後,可以使用send方法發送消息:

producer.send(message);

JMS消息消費者

消息消費者由Session創建,用於接受目的地發送的消息。消費者實現MessageConsumer介面,,我們可以為目的地、隊列或話題創建消費者;

MessageConsumer consumer = session.createConsumer(dest);
MessageConsumer consumer = session.createConsumer(queue);
MessageConsumer consumer = session.createConsumer(topic);

JMS消息監聽器

JMS消息監聽器是消息的預設事件處理者,他實現了MessageListener介面,該介面包含一個onMessage方法,在該方法中需要定義消息達到後的具體動作。通過調用setMessageListener方法我們給指定消費者定義了消息監聽器

Listener myListener = new Listener();
consumer.setMessageListener(myListener);

JMS消息結構

JMS客戶端使用JMS消息與系統通訊,JMS消息雖然格式簡單但是非常靈活, JMS消息由三部分組成:

消息頭

JMS消息頭預定義了若幹欄位用於客戶端與JMS提供者之間識別和發送消息,預編譯頭如下:

– JMSDestination
– JMSDeliveryMode
– JMSMessageID
– JMSTimestamp
– JMSCorrelationID
– JMSReplyTo
– JMSRedelivered
– JMSType
– JMSExpiration
– JMSPriority

消息屬性

我們可以給消息設置自定義屬性,這些屬性主要是提供給應用程式的。對於實現消息過濾功能,消息屬性非常有用,JMS API定義了一些標準屬性,JMS服務提供者可以選擇性的提供部分標準屬性。

消息體

在消息體中,JMS API定義了五種類型的消息格式,讓我們可以以不同的形式發送和接受消息,並提供了對已有消息格式的相容。不同的消息類型如下:

Text message : javax.jms.TextMessage,表示一個文本對象。
Object message : javax.jms.ObjectMessage,表示一個JAVA對象。
Bytes message : javax.jms.BytesMessage,表示位元組數據。
Stream message :javax.jms.StreamMessage,表示java原始值數據流。
Map message : javax.jms.MapMessage,表示鍵值對。

 

最後補充一下,常見的開源JMS服務的提供者,如下:

  • JBoss 社區所研發的 HornetQ
  • Joram
  • Coridan的MantaRay
  • The OpenJMS Group的OpenJMS

以上就是JMS的入門教程,在接下來的文章中,我將會編寫一些JMS的例子。

學習愉快~

 

譯文鏈接(做了部分修改,不是直接翻譯的~~):http://howtodoinjava.com/jms/jms-java-message-service-tutorial/

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ...
  • 最近剛剛接觸MVC不久,因項目中要用到分頁,網上找了下資料,最後採用了MvcPager(http://www.webdiyer.com/),支持同步和Ajax非同步分頁。廢話不多說了直接上代碼。 一.MvcPager非同步 ViewModel: public class Article { [Displ ...
  • 使用DataSet可以直接輸出XML,並可指定是否帶有Schema: 不過,這樣將不會輸出值為Null的欄位,如: 你可能希望結果是這樣: 但結果為: c沒有輸出在XML文件中,其實我覺得這樣更合理,否則,如何區分null和""呢?如果希望輸出c,那隻能通過XmlDocument自己寫了: 空節點顯 ...
  • WPF綁定數據 模型類(繼承 INotifyPropertyChanged,實現屬性的變更通知) 最後的實現效果: 方法一:前臺頁面不對數據做綁定,後臺對RadGridView控制項做數據綁定 方法二:前端頁面做 ItemsSource空綁定,後臺用DataContext綁定上下文數據 記錄完成。 ...
  • 在“如何用MediaCapture解決二維碼掃描問題”這篇文章中,我們通過“成像”、“截圖”與“識別”三個步驟介紹了使用MediaCapture掃碼的主要過程及註意事項。本文主要針對“識別”的過程,對Barcode的概念作出一個較為簡單的介紹,同時也會討論ZXing的使用方法。 ZXing是一個Ja ...
  • 在WEB系統中,列印的確是比較煩人的問題,如果我們能製作一個屬於自己的自定義的列印插件,那麼我們在後續自定義列印的時候能隨心所欲的控制列印,這樣的效果對於程式員來說是非常開心的一件事件,本文將自己開發編寫的C# 製作的HTML列印插件分享出來,讓有同樣需求的朋友提供一個參考;此插件是基於Micros ...
  • 基於Jenkins快速搭建持續集成環境.(Jenkins+tortoisesvn+MSBuild) ...
  • 在初級篇中,我們接觸了: 1.url 的簡單編寫 2.兩種傳參的方式 3.捕獲的參數總是字元串 4.為視圖設置預設參數 …… 在中級篇中將更進一步。 包含其它的URLconfs 當網站非常大的時候,將所有的url都寫在一個url模塊中會非常的臃腫,且後期不便於維護。此時,就可以使用包含的方式將部分的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...