1.JMS入門篇

什么是Java消息服務(wù)

Java消息服務(wù)指的是兩個應(yīng)用程序之間進(jìn)行異步通信的API状婶,它為標(biāo)準(zhǔn)消息協(xié)議和消息服務(wù)提供了一組通用接口提前,包括創(chuàng)建、發(fā)送字逗、讀取消息等京郑,用于支持JAVA應(yīng)用程序開發(fā)。在J2EE中葫掉,當(dāng)兩個應(yīng)用程序使用JMS進(jìn)行通信時些举,它們之間并不是直接相連的,而是通過一個共同的消息收發(fā)服務(wù)連接起來俭厚,可以達(dá)到解耦的效果户魏,我們將會在接下來的教程中詳細(xì)介紹。

為什么需要JMS

在JAVA中挪挤,如果兩個應(yīng)用程序之間對各自都不了解叼丑,甚至這兩個程序可能部署在不同的大洲上,那么它們之間如何發(fā)送消息呢扛门?舉個例子鸠信,一個應(yīng)用程序A部署在印度,另一個應(yīng)用程序部署在美國论寨,然后每當(dāng)A觸發(fā)某件事后星立,B想從A獲取一些更新信息。當(dāng)然葬凳,也有可能不止一個B對A的更新信息感興趣绰垂,可能會有N個類似B的應(yīng)用程序想從A中獲取更新的信息。

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

JMS同樣適用于基于事件的應(yīng)用程序荐健,如聊天服務(wù)酱畅,它需要一種發(fā)布事件機制向所有與服務(wù)器連接的客戶端發(fā)送消息。JMS與RMI不同江场,發(fā)送消息的時候纺酸,接收者不需要在線。服務(wù)器發(fā)送了消息址否,然后就不管了餐蔬;等到客戶端上線的時候,能保證接收到服務(wù)器發(fā)送的消息佑附。這是一個很強大的解決方案樊诺,能處理當(dāng)今世界很多普遍問題。

JMS的優(yōu)勢

異步

JMS天生就是異步的音同,客戶端獲取消息的時候词爬,不需要主動發(fā)送請求,消息會自動發(fā)送給可用的客戶端权均。

可靠

JMS保證消息只會遞送一次顿膨。大家都遇到過重復(fù)創(chuàng)建消息問題锅锨,而JMS能幫你避免該問題。

JMS消息傳送模型

在JMS API出現(xiàn)之前恋沃,大部分產(chǎn)品使用“點對點”和“發(fā)布/訂閱”中的任一方式來進(jìn)行消息通訊必搞。JMS定義了這兩種消息發(fā)送模型的規(guī)范,它們相互獨立囊咏。任何JMS的提供者可以實現(xiàn)其中的一種或兩種模型恕洲,這是它們自己的選擇。JMS規(guī)范提供了通用接口保證我們基于JMS API編寫的程序適用于任何一種模型匆笤。

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

點對點消息傳送模型

在點對點消息傳送模型中研侣,應(yīng)用程序由消息隊列,發(fā)送者炮捧,接收者組成。每一個消息發(fā)送給一個特殊的消息隊列惦银,該隊列保存了所有發(fā)送給它的消息(除了被接收者消費掉的和過期的消息)咆课。點對點消息模型有一些特性,如下:

每個消息只有一個接收者扯俱;

消息發(fā)送者和接收者并沒有時間依賴性书蚪;

當(dāng)消息發(fā)送者發(fā)送消息的時候,無論接收者程序在不在運行迅栅,都能獲取到消息殊校;

當(dāng)接收者收到消息的時候,會發(fā)送確認(rèn)收到通知(acknowledgement)读存。

發(fā)布/訂閱消息傳遞模型

在發(fā)布/訂閱消息模型中为流,發(fā)布者發(fā)布一個消息,該消息通過topic傳遞給所有的客戶端让簿。在這種模型中敬察,發(fā)布者和訂閱者彼此不知道對方,是匿名的且可以動態(tài)發(fā)布和訂閱topic尔当。topic主要用于保存和傳遞消息莲祸,且會一直保存消息直到消息被傳遞給客戶端。

發(fā)布/訂閱消息模型特性如下:

一個消息可以傳遞給多個訂閱者

發(fā)布者和訂閱者有時間依賴性椭迎,只有當(dāng)客戶端創(chuàng)建訂閱后才能接受消息锐帜,且訂閱者需一直保持活動狀態(tài)以接收消息。

為了緩和這樣嚴(yán)格的時間相關(guān)性畜号,JMS允許訂閱者創(chuàng)建一個可持久化的訂閱缴阎。這樣,即使訂閱者沒有被激活(運行)弄兜,它也能接收到發(fā)布者的消息药蜻。

接收消息

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

同步

使用同步方式接收消息的話,消息訂閱者調(diào)用receive()方法语泽。在receive()中贸典,消息未到達(dá)或在到達(dá)指定時間之前,方法會阻塞踱卵,直到消息可用廊驼。

異步

使用異步方式接收消息的話,消息訂閱者需注冊一個消息監(jiān)聽者惋砂,類似于事件監(jiān)聽器妒挎,只要消息到達(dá),JMS服務(wù)提供者會通過調(diào)用監(jiān)聽器的onMessage()遞送消息西饵。

JMS編程接口

JMS應(yīng)用程序由如下基本模塊組成:

管理對象(Administered objects)-連接工廠(Connection Factories)和目的地(Destination)

連接對象(Connections)

會話(Sessions)

消息生產(chǎn)者(Message Producers)

消息消費者(Message Consumers)

消息監(jiān)聽者(Message Listeners)

JMS管理對象

管理對象(Administered objects)是預(yù)先配置的JMS對象酝掩,由系統(tǒng)管理員為使用JMS的客戶端創(chuàng)建,主要有兩個被管理的對象:

連接工廠(ConnectionFactory)

目的地(Destination)

這兩個管理對象由JMS系統(tǒng)管理員通過使用Application Server管理控制臺創(chuàng)建眷柔,存儲在應(yīng)用程序服務(wù)器的JNDI名字空間或JNDI注冊表期虾。

連接工廠(ConnectionFactory)

客戶端使用一個連接工廠對象連接到JMS服務(wù)提供者,它創(chuàng)建了JMS服務(wù)提供者和客戶端之間的連接驯嘱。JMS客戶端(如發(fā)送者或接受者)會在JNDI名字空間中搜索并獲取該連接镶苞。使用該連接,客戶端能夠與目的地通訊鞠评,往隊列或話題發(fā)送/接收消息茂蚓。讓我們用一個例子來理解如何發(fā)送消息:

QueueConnectionFactory queueConnFactory = (QueueConnectionFactory) initialCtx.lookup ("primaryQCF");

Queue purchaseQueue= (Queue) initialCtx.lookup ("Purchase_Queue");

Queue returnQueue= (Queue) initialCtx.lookup ("Return_Queue");

目的地(Destination)

目的地指明消息被發(fā)送的目的地以及客戶端接收消息的來源。JMS使用兩種目的地剃幌,隊列和話題聋涨。如下代碼指定了一個隊列和話題。

創(chuàng)建一個隊列Session

QueueSession ses = con.createQueueSession (false, Session.AUTO_ACKNOWLEDGE);//get the Queue objectQueue t = (Queue) ctx.lookup ("myQueue");//create QueueReceiverQueueReceiver receiver = ses.createReceiver(t);

創(chuàng)建一個話題Session

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

JMS連接

連接對象封裝了與JMS提供者之間的虛擬連接锥忿,如果我們有一個ConnectionFactory對象牛郑,可以使用它來創(chuàng)建一個連接。

Connection connection = connectionFactory.createConnection();

創(chuàng)建完連接后敬鬓,需要在程序使用結(jié)束后關(guān)閉它:

connection.close();

JMS?會話(Session)

Session是一個單線程上下文淹朋,用于生產(chǎn)和消費消息,可以創(chuàng)建出消息生產(chǎn)者和消息消費者钉答。

Session對象實現(xiàn)了Session接口础芍,在創(chuàng)建完連接后,我們可以使用它創(chuàng)建Session数尿。

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

JMS消息生產(chǎn)者

消息生產(chǎn)者由Session創(chuàng)建仑性,用于往目的地發(fā)送消息。生產(chǎn)者實現(xiàn)MessageProducer接口右蹦,我們可以為目的地诊杆、隊列或話題創(chuàng)建生產(chǎn)者歼捐;

···

MessageProducer producer =session.createProducer(dest);

MessageProducer producer=session.createProducer(queue);

MessageProducer producer= session.createProducer(topic);

···

創(chuàng)建完消息生產(chǎn)者后,可以使用send方法發(fā)送消息:

producer.send(message);

JMS消息消費者

消息消費者由Session創(chuàng)建晨汹,用于接受目的地發(fā)送的消息豹储。消費者實現(xiàn)MessageConsumer接口,淘这,我們可以為目的地剥扣、隊列或話題創(chuàng)建消費者;

MessageConsumer consumer =session.createConsumer(dest);

MessageConsumer consumer=session.createConsumer(queue);

MessageConsumer consumer= session.createConsumer(topic);

JMS消息監(jiān)聽器

JMS消息監(jiān)聽器是消息的默認(rèn)事件處理者铝穷,他實現(xiàn)了MessageListener接口钠怯,該接口包含一個onMessage方法,在該方法中需要定義消息達(dá)到后的具體動作曙聂。通過調(diào)用setMessageListener方法我們給指定消費者定義了消息監(jiān)聽器

Listener myListener =newListener();

consumer.setMessageListener(myListener);

JMS消息結(jié)構(gòu)

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

消息頭

JMS消息頭預(yù)定義了若干字段用于客戶端與JMS提供者之間識別和發(fā)送消息宁脊,預(yù)編譯頭如下:

– JMSDestination

– JMSDeliveryMode

– JMSMessageID

– JMSTimestamp

– JMSCorrelationID

– JMSReplyTo

– JMSRedelivered

– JMSType

– JMSExpiration

– JMSPriority

消息屬性

我們可以給消息設(shè)置自定義屬性刽锤,這些屬性主要是提供給應(yīng)用程序的。對于實現(xiàn)消息過濾功能朦佩,消息屬性非常有用,JMS API定義了一些標(biāo)準(zhǔn)屬性庐氮,JMS服務(wù)提供者可以選擇性的提供部分標(biāo)準(zhǔn)屬性语稠。

消息體

在消息體中,JMS API定義了五種類型的消息格式弄砍,讓我們可以以不同的形式發(fā)送和接受消息仙畦,并提供了對已有消息格式的兼容。不同的消息類型如下:

Text message: javax.jms.TextMessage音婶,表示一個文本對象慨畸。

Object message: javax.jms.ObjectMessage,表示一個JAVA對象衣式。

Bytes message: javax.jms.BytesMessage寸士,表示字節(jié)數(shù)據(jù)。

Stream message:javax.jms.StreamMessage碴卧,表示java原始值數(shù)據(jù)流弱卡。

Map message: javax.jms.MapMessage,表示鍵值對住册。


常見的開源JMS服務(wù)的提供者

JBoss 社區(qū)所研發(fā)的 HornetQ

Joram

Coridan的MantaRay

The OpenJMS Group的OpenJMS

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末婶博,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子荧飞,更是在濱河造成了極大的恐慌凡人,老刑警劉巖名党,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異挠轴,居然都是意外死亡传睹,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門忠荞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蒋歌,“玉大人,你說我怎么就攤上這事委煤√糜停” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵碧绞,是天一觀的道長府框。 經(jīng)常有香客問我,道長讥邻,這世上最難降的妖魔是什么迫靖? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮兴使,結(jié)果婚禮上系宜,老公的妹妹穿的比我還像新娘。我一直安慰自己发魄,他們只是感情好盹牧,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著励幼,像睡著了一般汰寓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上苹粟,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天有滑,我揣著相機與錄音,去河邊找鬼嵌削。 笑死毛好,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的掷贾。 我是一名探鬼主播睛榄,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼想帅!你這毒婦竟也來了场靴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎旨剥,沒想到半個月后咧欣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡轨帜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年魄咕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚌父。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡哮兰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出苟弛,到底是詐尸還是另有隱情喝滞,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布膏秫,位于F島的核電站右遭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏缤削。R本人自食惡果不足惜窘哈,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望亭敢。 院中可真熱鬧滚婉,春花似錦、人聲如沸帅刀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽劝篷。三九已至,卻和暖如春民宿,著一層夾襖步出監(jiān)牢的瞬間娇妓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工活鹰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留哈恰,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓志群,卻偏偏與公主長得像着绷,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子锌云,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理荠医,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,661評論 18 139
  • ActiveMQ 即時通訊服務(wù) 淺析http://www.cnblogs.com/hoojo/p/active_m...
    bboymonk閱讀 1,490評論 0 11
  • 1彬向、前言 之前我們通過兩篇文章(架構(gòu)設(shè)計:系統(tǒng)間通信(19)——MQ:消息協(xié)議(上)兼贡、架構(gòu)設(shè)計:系統(tǒng)間通信(20)...
    境里婆娑閱讀 1,885評論 0 4
  • 什么是JMS Java消息服務(wù)(Java Message Service,簡稱JMS)是用于訪問企業(yè)消息系統(tǒng)的開發(fā)...
    zach_undefined閱讀 3,704評論 0 1
  • 一娃胆、 消息隊列概述 消息隊列中間件是分布式系統(tǒng)中重要的組件遍希,主要解決應(yīng)用耦合、異步消息里烦、流量削鋒等問題凿蒜。實現(xiàn)高性能...
    步積閱讀 56,945評論 10 138