複製鏈接
請複製以下鏈接發送給好友

Java消息服務

鎖定
Java 消息服務(Java Message Service,JMS)應用程序接口是一個Java 平台中關於面向消息中間件(MOM)的API,用於在兩個應用程序之間,或分佈式系統中發送消息,進行異步通信。Java 消息服務是一個與具體平台無關的 API,絕大多數 MOM 提供商都對 JMS 提供支持。
中文名
Java消息服務
外文名
JavaMessageService
簡    稱
JMS
平    台
JAVA

Java消息服務消息服務簡介

Java 消息服務(Java Message Service,JMS)是一種與廠商無關的 API,用來訪問消息收發系統。它類似於 JDBC (Java Database Connectivity):這裏,JDBC 是可以用來訪問許多不同關係數據庫的 API,而 JMS 則提供同樣與廠商無關的訪問方法,以訪問消息收發服務。許多廠目前都支持 JMS,包括 IBM 的 MQSeries、BEA的 Weblogic JMS service和 Progress 的 SonicMQ,這只是幾個例子。 JMS 使您能夠通過消息收發服務(有時稱為消息中介程序或路由器)從一個 JMS 客户機向另一個 JML 客户機發送消息。消息是 JMS 中的一種類型對象,由兩部分組成:報頭和消息主體。報頭由路由信息以及有關該消息的元數據組成。消息主體則攜帶着應用程序的數據或有效負載。根據有效負載的類型來劃分,可以將消息分為幾種類型,它們分別攜帶:簡單文本 (TextMessage)、可序列化的對象 (ObjectMessage)、屬性集合 (MapMessage)、字節流 (BytesMessage)、原始值流 (StreamMessage),還有無有效負載的消息 (Message)。
通信傳遞的消息交換了計算機之間至關重要的數據——而非用户之間——並且包含了例如事件通知和服務請求之類的信息。通信通常用來協調在不同的系統中或是用不同的編程語言所寫的程序。
使用JMS接口,程序員可以調用IBM的MQSeries,Progress Software的SonicMQ和其他流行通信產品商家的消息服務。另外,JMS支持包含串行Java對象的消息和包含可擴展標記語言(XML)頁面的消息。 [1] 

Java消息服務模式

Java 消息服務的規範包括兩種消息模式,點對點和發佈者/訂閲者。許多提供商支持這一通用框架因此,程序員可以在他們的分佈式軟件中實現面向消息的操作,這些操作將具有不同面向消息中間件產品的可移植性。
Java 消息服務支持同步和異步的消息處理,在某些場景下,異步消息是必要的;在其他場景下,異步消息比同步消息操作更加便利。
Java 消息服務支持面向事件的方法接收消息,事件驅動的程序設計現在被廣泛認為是一種富有成效的程序設計範例,程序員們都相當熟悉。
在應用系統開發時,Java 消息服務可以推遲選擇面對消息中間件產品,也可以在不同的面對消息中間件切換。 [2] 

Java消息服務異步消息收發

消息收發系統是異步的,也就是説,JMS 客户端可以發送消息而不必等待迴應。比較可知,這完全不同於基於 RPC 的(基於遠程過程的)系統,如 EJB 1.1、CORBA 和 Java RMI 的引用實現。在 RPC 中,客户機調用服務器上某個分佈式對象的一個方法。在方法調用返回之前,該客户機被阻塞;該客户機在可以執行下一條指令之前,必須等待方法調用結束。在 JMS 中,客户機將消息發送給一個虛擬通道(主題或隊列),而其它 JMS 客户機則預訂或監聽這個虛擬通道。當 JMS 客户機發送消息時,它並不等待迴應。它執行發送操作,然後繼續執行下一條指令。消息可能最終轉發到一個或許多個客户機,這些客户機都不需要作出迴應。
JMS 的通用接口集合以異步方式發送或接收消息。異步方式接收消息顯然是使用間斷網絡連接的客户機,諸如移動電話和PDA的最好的選擇。另外, JMS 採用一種寬鬆結合方式整合企業系統的方法,其主要的目的就是創建能夠使用跨平台數據信息的、可移植的企業級應用程序,而把開發人力解放出來。 [1] 

Java消息服務傳遞消息方式

JMS 有兩種傳遞消息的方式。標記為 NON_PERSISTENT 的消息最多投遞一次,而標記為 PERSISTENT 的消息將使用暫存後再轉送的機理投遞。如果一個 JMS 服務離線,那麼持久性消息不會丟失,但是得等到這個服務恢復聯機時才會被傳遞。所以默認的消息傳遞方式是非持久性的。即使使用非持久性消息可能降低內務和需要的存儲器,並且這種傳遞方式只有當你不需要接收所有的消息時才使用。
雖然 JMS 規範並不需要 JMS 供應商實現消息的優先級路線,但是它需要遞送加快的消息優先於普通級別的消息。JMS 定義了從 0 到 9 的優先級路線級別,0 是最低的優先級而 9 則是最高的。更特殊的是 0 到 4 是正常優先級的變化幅度,而 5 到 9 是加快的優先級的變化幅度。舉例來説: topicPublisher.publish (message, DeliveryMode.PERSISTENT, 8, 10000); //Pub-Sub 或 queueSender.send(message, DeliveryMode.PERSISTENT, 8, 10000);//P2P  這個代碼片斷,有兩種消息模型,映射遞送方式是持久的,優先級為加快型,生存週期是10000 (以毫秒度量 )。如果生存週期設置為零,這則消息將永遠不會過期。當消息需要時間限制否則將使其無效時,設置生存週期是有用的。 [2] 

Java消息服務消息正文格式

JMS 定義了五種不同的消息正文格式,以及調用的消息類型,允許你發送並接收以一些不同形式的數據,提供現有消息格式的一些級別的兼容性。
· StreamMessage -- Java原始值的數據流
· MapMessage--一套名稱-值對
· TextMessage--一個字符串對象
· ObjectMessage--一個序列化的 Java對象
· BytesMessage--一個未解釋字節的數據流
JMS應用程序接口提供用於創建每種類型消息和設置荷載的方法例如,為了在一個隊列創建併發送一個TextMessage實例,你可以使用下列語句: TextMessage message = queueSession.createTextMessage(); message.setText(textMsg);  以異步方式接收消息,需要創建一個消息監聽器然後註冊一個或多個使用MessageConsumer的JMS MessageListener接口。會話(主題或隊列)負責產生某些消息,這些消息被傳送到使用onMessage方法的監聽者那裏。 import javax.jms.*; public class ExampleListener implements MessageListener { //把消息強制轉化為TextMessage格式 public void onMessage(Message message) { TextMessage textMsg = null; // 打開並處理這段消息 } }  當我們創建QueueReceiver和TopicSubscriber時,我們傳遞消息選擇器字符串: //P2P QueueReceiver QueueReceiver receiver; receiver = session.createReceiver(queue, selector); //Pub-Sub TopicSubscriber TopicSubscriber subscriber; subscriber = session.createSubscriber(topic, selector);
為了啓動消息的交付,不論是Pub/Sub還是P2P,都需要調用start方法。
當一條消息被捕捉時,這條消息做為一條必須被強制轉化為適當消息類型的普通Message對象到達。這是一個被用來提取或打開消息內容的getter方法。下列代碼片段使用StreamMessage類型。 private void unPackMessage (Message message) { String eName; String position; double rate; StreamMessage message; Message = session.createStreamMessage( ); //注意下面的代碼必須按照我給出的順序書寫 message.writeString(eName); message.writeString(position); message.writeDouble(rate); //實現處理消息的必要的程序邏輯 }
停止消息的傳遞,無論是Pub/Sub還是P2P,都調用stop方法。 TopicConnection.start( ); //pub-sub QueueConnection.start( ); //P2P TopicConnection.start ( );// pub-sub QueueConnection.start ( );// P2P  其他的J2EE組件--servletEJB--可以當作消息生產者;然而,它們可能只能同步操作,這可能是因為它們的請求-應答的性質決定的。雖然XML目前還不是被支持的消息類型,發送一個XML文件和創建一條文本類型消息以及把XML文件添加到消息的有效負載都一樣簡單,都是以非專有的方式傳送數據。值得注意的是,一些JMS供應廠商已經提供了可用的XML消息類型。但是使用非標準的消息類型可能會出現可移植性問題。 String reportData; //reportData內容為XML 文檔 TextMessage message; message = session.createTextMessage(); message.setText (reportData); [1] 

Java消息服務消息驅動組件

MDB 是一個當消息到達時被容器調用的異步消息消費程序。與 entity 和 session EJB 不同,MDB 沒有本地和遠程接口並且是匿名的;它們對於客户是不可見的。MDB 是 JMS 系統的一部分,作為消費者實現服務器上的商業邏輯程序。 一個客户程序可能通過使用 JNDI 定位一個與 MDB 相關聯的 JMS。 例如: Context initialContext = new InitialContext(); Queue reportInfoQueue = (javax.jms.Queue)initialContext.lookup (“java:comp/env/jms/reportInfoQueue”);  MDB是由Bean類和相應的XML部署描述符組成。 Bean 類實現MessageDriveBean 接口: import javax.ejb.*; import jms.Message.*; public interface MessageDriveBean { public void ejbCreate(); public void ejbRemove(); public void setMessageDrivenContext(MessageDrivenContext ctx); }  消息監聽器接口: import javax.jms.*; public interface MessageListener { public void onMessage( ); }

Java消息服務使用舉例

既然我現在已經有了一些基本的 JMS知識,那麼我們可以使用 JMS 做什麼呢?任何事情都可以。例如,分別用於銷售、庫存、客户服務和賬目處理的系統。這些部門之間的系統很可能已經存在了很長時間,這些處理要求把事務移動到系統中去,這並不是一個小的工作。這就是消息服務適用的地點。
當售貨員完成銷售的時候,一條消息被髮給庫存系統;一旦訂單消息發送給收發貨人員,就可以按照訂單出貨了。當訂單成功地發貨,系統將通知顧客服務會計系統這個訂單已經成功的交易了。所有對應的每個子系統都自動地根據收到的消息進行更新。
JMS 一般都不是用來整合一個系統,而是整合許多可能參與消息驅動環境的系統。JMS 是一個用於開發和集成企業應用程序的重要的工具。因為許多公司都有以前遺留下來的系統和新近開發的系統綜合起來的情況,消息的使用是整合整個企業的重要步驟。 [2] 
參考資料
  • 1.    "Java Message Service Documentation". Sun Microsystems. October 30, 1998. Archived from the original on 1999-02-24. Retrieved July 31, 2018.
  • 2.    "JSR 343: Java Message Service 2.0". The Java Community Process Program. Retrieved July 31, 2018.