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

什麼是Java消息服務 

  Java消息服務指的是兩個應用程序之間進行異步通訊的API,它爲標準消息協議和消息服務提供了一組通用接口,包括建立、發送、讀取消息等,用於支持JAVA應用程序開發。在J2EE中,當兩個應用程序使用JMS進行通訊時,它們之間並非直接相連的,而是經過一個共同的消息收發服務鏈接起來,能夠達到解耦的效果,咱們將會在接下來的教程中詳細介紹。html

爲何須要JMS

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

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

  JMS一樣適用於基於事件的應用程序,如聊天服務,它須要一種發佈事件機制向全部與服務器鏈接的客戶端發送消息。JMS與RMI不一樣,發送消息的時候,接收者不須要在線。服務器發送了消息,而後就無論了;等到客戶端上線的時候,能保證接收到服務器發送的消息。這是一個很強大的解決方案,能處理當今世界不少廣泛問題。編程

JMS的優點

異步

  JMS天生就是異步的,客戶端獲取消息的時候,不須要主動發送請求,消息會自動發送給可用的客戶端。服務器

可靠

  JMS保證消息只會遞送一次。你們都遇到太重複建立消息問題,而JMS能幫你避免該問題。session

JMS消息傳送模型

  在JMS API出現以前,大部分產品使用「點對點」和「發佈/訂閱」中的任一方式來進行消息通信。JMS定義了這兩種消息發送模型的規範,它們相互獨立。任何JMS的提供者能夠實現其中的一種或兩種模型,這是它們本身的選擇。JMS規範提供了通用接口保證咱們基於JMS API編寫的程序適用於任何一種模型。異步

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

點對點消息傳送模型

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

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

發佈/訂閱消息傳遞模型

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

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

  • 一個消息能夠傳遞給多個訂閱者
  • 發佈者和訂閱者有時間依賴性,只有當客戶端建立訂閱後才能接受消息,且訂閱者需一直保持活動狀態以接收消息。
  • 爲了緩和這樣嚴格的時間相關性,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使用示例

基於Tomcat + JNDI + ActiveMQ實現JMS的點對點消息傳送

JMS發佈/訂閱消息傳送例子

譯文連接(作了部分修改~~)

http://howtodoinjava.com/jms/jms-java-message-service-tutorial/

 

 

以上就是JMS的入門教程,學習愉快~

相關文章
相關標籤/搜索