java中間件之jms

一男旗、JMS簡介

1.1 JMS是什么

JMS Java Message Service Java消息服務(wù)。是JAVA EE中的一個技術(shù)欣鳖,JMS定義了JAVA中訪問消息中間件的接口察皇。類似JDBC。定義了接口,并不具體實(shí)現(xiàn)什荣。實(shí)現(xiàn)JMS接口消息的中間件稱為JMS Provider.例如:ActiveMQ.

Java消息服務(wù)是一個與具體平臺無關(guān)的API矾缓,絕大多數(shù)MOM提供商都對JMS提供支持(百度百科給出的概述)。我們可以簡單的理解:兩個應(yīng)用程序之間需要進(jìn)行通信稻爬,我們使用一個JMS服務(wù)嗜闻,進(jìn)行中間的轉(zhuǎn)發(fā),通過JMS 的使用桅锄,我們可以解除兩個程序之間的耦合琉雳。

1.2 JMS的優(yōu)勢  

Asynchronous(異步)

JMS is asynchronous by default. So to receive a message, the client is not required to send the request. The message will arrive automatically to the client as they become available.(JMS 原本就是一個異步的消息服務(wù),客戶端獲取消息的時候友瘤,不需要主動發(fā)送請求翠肘,消息會自動發(fā)送給可用的客戶端)


Reliable(可靠)

JMS provides the facility of assurance that the message will delivered once and only once. You know that duplicate messages create problems. JMS helps you avoiding such problems.(JMS保證消息只會遞送一次。大家都遇到過重復(fù)創(chuàng)建消息問題辫秧,而JMS能幫你避免該問題束倍。)

1.3 JMS的可靠性機(jī)制

消息確認(rèn)JMS消息只有被確認(rèn)之后,才能認(rèn)為被成功的消費(fèi)了盟戏。一般消息被成功消費(fèi)分三個步驟绪妹,客戶接受消息,處理消息柿究,確認(rèn)消息邮旷。消息何時被確認(rèn)取決于創(chuàng)建會話時的應(yīng)答模式。應(yīng)答模式有三種:?1.Session.AUTO_ACKNOWLEDGE:客戶從receive方法成功返回笛求,或者從MessageListener.onMessage方法成功返回時候廊移,會話自動確認(rèn)客戶收到消息。?2.Session_CLIENT_ACKNOWLEDGE:客戶通過調(diào)用acknowledge方法確認(rèn)消息探入。這個確認(rèn)是會話級別的確認(rèn)狡孔。也就是說只要確認(rèn)一個被消費(fèi)消息,那么這個會話上的所有被消費(fèi)的消息都會被確認(rèn)蜂嗽。?3.Session_DUPS_ACKNOWLEDGE:會話遲鈍的確認(rèn)消息苗膝。選擇這個模式有可能出現(xiàn)重復(fù)的消息。JMSRedelivered會是true.

消息持久性JMS支持兩種消息提交模式:?1.PERSISTENT:持久模式植旧。?2.NON_PERSISTENT:非持久模式辱揭。這個兩種模式上面有介紹。

消息優(yōu)先級消息優(yōu)先級病附,等級從0-9.默認(rèn)為4.數(shù)值越大问窃,優(yōu)先級越高。

消息過期消息過期時間完沪。默認(rèn)為永久不過期域庇。

持久訂閱持久訂閱嵌戈,首先消息的生產(chǎn)者必須使用持久模式提交信息,消費(fèi)者可以通過createDurableSubscriber方法來創(chuàng)建一個持久訂閱听皿。持久訂閱在某一個時刻只能有一個激活的訂閱者熟呛。持久訂閱創(chuàng)建之后會一直保存,直到應(yīng)用程序在會話上調(diào)用unsubcribe方法尉姨。

本地事物JMS session提供了commit與rollback方法來控制事物庵朝。事物提交意味著生產(chǎn)的所有消息被提交,消費(fèi)的所有消息被確認(rèn)又厉【鸥回滾意味著生產(chǎn)的所有消息被銷毀,消費(fèi)的所有消息被恢復(fù)并重新提交覆致,除非它們過期昔逗。

1.4 JMS的API結(jié)構(gòu)

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

(2)連接對象(Connections)

(3)會話(Sessions)

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

(5)消息消費(fèi)者(Message Consumers)

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


(1)、Connection Factories

創(chuàng)建Connection對象的工廠篷朵,針對兩種不同的jms消息模型,分別有QueueConnectionFactory和TopicConnectionFactory兩種婆排∩可以通過JNDI來查找ConnectionFactory對象《沃唬客戶端使用一個連接工廠對象連接到JMS服務(wù)提供者腮猖,它創(chuàng)建了JMS服務(wù)提供者和客戶端之間的連接。JMS客戶端(如發(fā)送者或接受者)會在JNDI名字空間中搜索并獲取該連接赞枕。使用該連接澈缺,客戶端能夠與目的地通訊,往隊(duì)列或話題發(fā)送/接收消息炕婶。


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

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

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

[if !supportLists](2)[endif]姐赡、Destination

目的地指明消息被發(fā)送的目的地以及客戶端接收消息的來源。JMS使用兩種目的地柠掂,隊(duì)列和話題项滑。如下代碼指定了一個隊(duì)列和話題:

創(chuàng)建一個隊(duì)列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);

(3)、Connection

Connection表示在客戶端和JMS系統(tǒng)之間建立的鏈接(對TCP/IP socket的包裝)涯贞。Connection可以產(chǎn)生一個或多個Session枪狂。跟ConnectionFactory一樣,Connection也有兩種類型:QueueConnection和TopicConnection宋渔。

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

Connection connection = connectionFactory.createConnection();

(4)严蓖、Session

Session是我們對消息進(jìn)行操作的接口,可以通過session創(chuàng)建生產(chǎn)者、消費(fèi)者谈飒、消息等岂座。Session 提供了事務(wù)的功能,如果需要使用session發(fā)送/接收多個消息時杭措,可以將這些發(fā)送/接收動作放到一個事務(wù)中费什。


我們可以在連接創(chuàng)建完成之后創(chuàng)建session:

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

這里面提供了參數(shù)兩個參數(shù),第一個參數(shù)是是否支持事務(wù)手素,第二個是事務(wù)的類型

(5)鸳址、Producter

消息生產(chǎn)者由Session創(chuàng)建,用于往目的地發(fā)送消息泉懦。生產(chǎn)者實(shí)現(xiàn)MessageProducer接口稿黍,我們可以為目的地、隊(duì)列或話題創(chuàng)建生產(chǎn)者崩哩;

MessageProducer producer = session.createProducer(dest);

MessageProducer producer = session.createProducer(queue);

MessageProducer producer = session.createProducer(topic);

(6)巡球、Consumer

消息消費(fèi)者由Session創(chuàng)建,用于接收被發(fā)送到Destination的消息邓嘹。

MessageConsumer consumer = session.createConsumer(dest);

MessageConsumer consumer = session.createConsumer(queue);

MessageConsumer consumer = session.createConsumer(topic);

(7)酣栈、MessageListener

消息監(jiān)聽器。如果注冊了消息監(jiān)聽器汹押,一旦消息到達(dá)矿筝,將自動調(diào)用監(jiān)聽器的onMessage方法。EJB中的MDB(Message-Driven Bean)就是一種MessageListener棚贾。

1.5 JMS應(yīng)用的基本步驟

(1)創(chuàng)建Connection Factory

(2)通過factory創(chuàng)建Connection窖维。

(3)啟動Connection

(4)通過Connection創(chuàng)建JMS Session

(5)session創(chuàng)建destination

(6)session創(chuàng)建producer 并設(shè)置destination。

(7)session創(chuàng)建consumer,設(shè)置目的地妙痹≈罚或者注冊一個JMS Message listener.

(8)發(fā)送或者接受Message(s)

(9)關(guān)閉所有JMS資源。

二细诸、JMS基本概念

2.1 JMS Message

JMS Message JMS消息沛贪,JMS消息由三部分組成?(1)消息頭:每個消息頭都有對應(yīng)的setter、getter方法震贵。?(2)消息屬性:如果需要除消息頭以外的值利赋,可以使用消息屬性。(3)消息體:封裝具體的消息數(shù)據(jù)猩系。

2.2 JMS producer

JMS Producer:消息生產(chǎn)者媚送,創(chuàng)建和發(fā)送JMS Message的客戶端應(yīng)用。

2.3 JMS consumer

JMS Consumer:消息消費(fèi)者寇甸,接收和處理JMS Message的客戶端應(yīng)用塘偎。消息的消費(fèi)可以采取以下兩種消費(fèi)方式疗涉。?(1)同步消費(fèi):通過調(diào)用消費(fèi)者的receive方法從目的地中顯示的提取消息,receive方法會一直阻塞吟秩,知道消息到達(dá)咱扣。?

(2)異步消費(fèi):通過為消費(fèi)者注冊一個消息監(jiān)聽器,定義消息到達(dá)時采取的動作涵防。

2.4 JMS domains

JMS domains: 消息傳遞域闹伪。也可以理解為消息傳遞的方式。JMS規(guī)范中定義了兩種消息傳遞的機(jī)制壮池,點(diǎn)對點(diǎn)(point-to-point, 簡寫PTP)和發(fā)布/訂閱(publish/subscribe,簡寫pub/sub).?1.PTP的特點(diǎn)如下:?(1)每個消息只能有一個消費(fèi)者偏瓤。PTP目的地被稱為隊(duì)列(Queue)。?(2)消費(fèi)者和生產(chǎn)者之間沒有時間相關(guān)性椰憋。也就是說消息生產(chǎn)者不管消費(fèi)者是否處于運(yùn)行狀態(tài)都可以發(fā)送消息厅克,而消費(fèi)者也可以不管生產(chǎn)者是否在線都可以接收消息。?


2.pub/sub特點(diǎn)橙依。?(1)每個消息可以有多個消費(fèi)者证舟。生產(chǎn)者把消息發(fā)布到一個“主題”上。?(2)生產(chǎn)者和消費(fèi)者之間有時間相關(guān)性窗骑。也就是說褪储,消費(fèi)者只能消費(fèi)它訂閱的主題之后,主題發(fā)布的消息慧域。而且如果沒有進(jìn)行持久訂閱,那么消費(fèi)者只能消費(fèi)在線時生產(chǎn)者發(fā)布的消息浪读。JMS規(guī)范允許進(jìn)行持久訂閱昔榴。一定程度上減少了時間的相關(guān)性。pub/sub目的地被稱為主題(Topic)?


2.5 Connection Factory

connection factory:連接工廠碘橘,用來創(chuàng)建連接到JMS Provider連接對象互订。

2.6 JMS Connection

connection:連接對象。封裝了客戶與JMS Provider的一個虛擬連接痘拆。

2.7 JMS Session

session:生產(chǎn)和消費(fèi)消息的一個單線程上下文仰禽。會話用于創(chuàng)建生產(chǎn)者、消費(fèi)者纺蛆、目的地吐葵、消息等,會話提供了一個事物性的上下文桥氏,在會話中温峭,一組發(fā)送和接收消息被組合到一個操作中。

2.8 Destination

destination:消息發(fā)送和接收的目的地字支。

2.9 JMS Client

client:用來接收消息的應(yīng)用凤藏。

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

JMS Message由消息頭奸忽,消息屬性,消息體三部分組成揖庄。

2.11 JMS消息頭

消息頭包含消息的識別信息和路由信息栗菜,消息頭的一些標(biāo)準(zhǔn)屬性如下:1.JMSDestination:消息發(fā)送目的地,由Send方法設(shè)置蹄梢,主要指點(diǎn)對點(diǎn)中的Queue與pub/sub中的Topic,自動分配疙筹。?2.JMSDeliveryMode:傳送模式,傳送模式分為如下兩種:?(1)持久模式:一條持久性的消息應(yīng)該被傳送“一次僅僅一次”。一次就是這個消息一定會被傳遞一次检号。例如JMS提供者出現(xiàn)故障腌歉,那么在恢復(fù)之后這條消息不會丟失,會再次被傳遞齐苛,直到成功翘盖。僅僅一次,就只要傳遞成功就不會再次被傳遞凹蜂。?(2)非持久模式:一條非持久的消息“最多被傳送一次“馍驯。最多一次意味著這條消息有可能丟失。如服務(wù)器故障玛痊,恢復(fù)后次消息會被丟失汰瘫。?3.JMSExpiration:由Send方法設(shè)置。消息過期時間擂煞。默認(rèn)為永久不過期混弥。?4.JMSPriority:消息優(yōu)先級,等級從0-9.默認(rèn)為4.數(shù)值越大对省,優(yōu)先級越高蝗拿。?5.JMSMessageID:唯一識別每個消息的標(biāo)志。由JMS Provider產(chǎn)生蒿涎,自動分配哀托。?6.JMSTimestamp:JMS Provider調(diào)用Send方法時候自動設(shè)置,是消息被返送和消息被消費(fèi)之間的實(shí)際時間差劳秋。?7.JMSCorrelationID:用來連接到另外一個消息仓手。典型的應(yīng)用就是在回復(fù)消息中連接到原消息。JMSCorrelationID可以由開發(fā)者設(shè)置稱為任何值玻淑。?8.JMSReplyTo: 提供本消息回復(fù)消息的目的地地址嗽冒。由開發(fā)者設(shè)置。?9.JMSType: 消息類型識別符补履,由開發(fā)者設(shè)置辛慰。?10.JMSRedelivered:這個有兩個值,true或者false干像。如果為true說明這條消息被客戶端收到過帅腌,但是因?yàn)槟撤N原因沒有被簽收驰弄。

2.12 JMS消息屬性

消息屬性包含三種類型:(1)應(yīng)用程序添加的屬性。如:message.setStringProperty(“userName”,”張三”);?(2)JMS定義的屬性速客。使用”JMSX”作為屬性的前綴名戚篙。?(3)JMS供應(yīng)商定義的屬性。

2.13 JMS消息體

- JMS API定義了5中形式的消息體溺职,也可以理解為5中消息類型岔擂。TextMessage、MapMessage浪耘、BytesMessage乱灵、StreamMessage、ObjectMessage.


三七冲、JMS的消息模型

3.1 JMS具有兩種通信模式

1痛倚、Point-to-Point Messaging Domain (點(diǎn)對點(diǎn))

2、Publish/Subscribe Messaging Domain (發(fā)布/訂閱模式)

   在JMS API出現(xiàn)之前澜躺,大部分產(chǎn)品使用“點(diǎn)對點(diǎn)”和“發(fā)布/訂閱”中的任一方式來進(jìn)行消息通訊蝉稳。JMS定義了這兩種消息發(fā)送模型的規(guī)范,它們相互獨(dú)立掘鄙。任何JMS的提供者可以實(shí)現(xiàn)其中的一種或兩種模型耘戚,這是它們自己的選擇。JMS規(guī)范提供了通用接口保證我們基于JMS API編寫的程序適用于任何一種模型操漠。

3.2 JMS模式

JMS為發(fā)開者提供了很多的要素收津,看一下比較重要的幾個:

3.3 JMS點(diǎn)對點(diǎn)通信模型

Point-to-Point Messaging Domain(點(diǎn)對點(diǎn)通信模型)


涉及到的概念:在點(diǎn)對點(diǎn)通信模式中,應(yīng)用程序由消息隊(duì)列浊伙,發(fā)送方朋截,接收方組成。每個消息都被發(fā)送到一個特定的隊(duì)列吧黄,接收者從隊(duì)列中獲取消息。隊(duì)列保留著消息唆姐,直到他們被消費(fèi)或超時拗慨。


特點(diǎn):

(1)每個消息只要一個消費(fèi)者

(2)發(fā)送者和接收者在時間上是沒有時間的約束,也就是說發(fā)送者在發(fā)送完消息之后奉芦,不管接收者有沒有接受消息赵抢,都不會影響發(fā)送方發(fā)送消息到消息隊(duì)列中。

(3)發(fā)送方不管是否在發(fā)送消息声功,接收方都可以從消息隊(duì)列中去到消息(The receiver can fetch message whether it is running or not when the sender sends the message)

(4)接收方在接收完消息之后烦却,需要向消息隊(duì)列應(yīng)答成功

3.4 JMS發(fā)布/訂閱通信模型

Publish/Subscribe Messaging Domain(發(fā)布/訂閱通信模型)


涉及到的概念:在發(fā)布/訂閱消息模型中,發(fā)布者發(fā)布一個消息先巴,該消息通過topic傳遞給所有的客戶端其爵。該模式下冒冬,發(fā)布者與訂閱者都是匿名的,即發(fā)布者與訂閱者都不知道對方是誰摩渺。并且可以動態(tài)的發(fā)布與訂閱Topic简烤。Topic主要用于保存和傳遞消息,且會一直保存消息直到消息被傳遞給客戶端摇幻。


特點(diǎn):

(1)一個消息可以傳遞個多個訂閱者(即:一個消息可以有多個接受方)

(2)發(fā)布者與訂閱者具有時間約束横侦,針對某個主題(Topic)的訂閱者,它必須創(chuàng)建一個訂閱者之后绰姻,才能消費(fèi)發(fā)布者的消息枉侧,而且為了消費(fèi)消息,訂閱者必須保持運(yùn)行的狀態(tài)狂芋。

(3)為了緩和這樣嚴(yán)格的時間相關(guān)性榨馁,JMS允許訂閱者創(chuàng)建一個可持久化的訂閱。這樣银酗,即使訂閱者沒有被激活(運(yùn)行)辆影,它也能接收到發(fā)布者的消息。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末黍特,一起剝皮案震驚了整個濱河市蛙讥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌灭衷,老刑警劉巖次慢,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異翔曲,居然都是意外死亡迫像,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進(jìn)店門瞳遍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闻妓,“玉大人,你說我怎么就攤上這事掠械∮衫拢” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵猾蒂,是天一觀的道長均唉。 經(jīng)常有香客問我,道長肚菠,這世上最難降的妖魔是什么舔箭? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮蚊逢,結(jié)果婚禮上层扶,老公的妹妹穿的比我還像新娘箫章。我一直安慰自己,他們只是感情好怒医,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布炉抒。 她就那樣靜靜地躺著,像睡著了一般稚叹。 火紅的嫁衣襯著肌膚如雪焰薄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天扒袖,我揣著相機(jī)與錄音塞茅,去河邊找鬼。 笑死季率,一個胖子當(dāng)著我的面吹牛野瘦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播飒泻,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼鞭光,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了泞遗?” 一聲冷哼從身側(cè)響起惰许,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎史辙,沒想到半個月后汹买,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡聊倔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年晦毙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耙蔑。...
    茶點(diǎn)故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡见妒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出甸陌,到底是詐尸還是另有隱情须揣,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布邀层,位于F島的核電站,受9級特大地震影響遂庄,放射性物質(zhì)發(fā)生泄漏寥院。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一涛目、第九天 我趴在偏房一處隱蔽的房頂上張望秸谢。 院中可真熱鬧凛澎,春花似錦、人聲如沸估蹄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽臭蚁。三九已至最铁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間垮兑,已是汗流浹背冷尉。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留系枪,地道東北人雀哨。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像私爷,于是被迫代替她去往敵國和親雾棺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評論 2 351

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

  • ActiveMQ 即時通訊服務(wù) 淺析http://www.cnblogs.com/hoojo/p/active_m...
    bboymonk閱讀 1,482評論 0 11
  • 深入掌握J(rèn)MS(一):JMS基礎(chǔ) 1. JMS基本概念 JMS(Java Message Service) 即Ja...
    天天嗦螺螄粉閱讀 286評論 0 0
  • 1衬浑、什么是JMS JMS即Java消息服務(wù)(Java Message Service)應(yīng)用程序接口捌浩,是一個Java...
    逐夢余生閱讀 1,416評論 0 1
  • 什么是Java消息服務(wù) Java消息服務(wù)指的是兩個應(yīng)用程序之間進(jìn)行異步通信的API,它為標(biāo)準(zhǔn)消息協(xié)議和消息服務(wù)提供...
    雨帶著眼淚滑落閱讀 961評論 1 4
  • 問我嚎卫,喜歡配音的初衷是什么嘉栓? 我說,因?yàn)橄矚g那種配音的體驗(yàn)拓诸。作為素人侵佃,我們只有一個軀體。 可是伴隨著對虛擬世界的喜...
    71c563954e37閱讀 486評論 2 5