【JMS】JMS详解
一、JMS介紹
??????JMS即Java消息服務(wù)(Java Message Service)應(yīng)用程序接口,是一個(gè)Java平臺(tái)中關(guān)于面向消息中間件(MOM)的API,用于在兩個(gè)應(yīng)用程序之間,或者在分布式系統(tǒng)中發(fā)送消息,進(jìn)行異步通信。Java消息服務(wù)是一個(gè)與具體平臺(tái)無(wú)關(guān)的API,絕大多數(shù)MOM提供商都對(duì)JMS提供支持。
??????JMS源于企業(yè)應(yīng)用對(duì)于消息中間件的需求,使應(yīng)用程序可以通過(guò)消息進(jìn)行異步處理而互不影響。Sun公司和他的合作伙伴設(shè)計(jì)的JMS API定義了一組公共的應(yīng)用程序接口和相應(yīng)語(yǔ)法,使得Java程序能夠和其它消息組件進(jìn)行通信。JMS可以使你通過(guò)消息收發(fā)服務(wù)(有時(shí)稱為消息中介程序或路由器)從一個(gè)JMS客戶機(jī)向另一個(gè)JMS客戶機(jī)發(fā)送消息。
二、JMS的體系架構(gòu)
JMS由以下元素組成:
1、JMS提供者
連接面向消息中間件的,JMS接口的一個(gè)實(shí)現(xiàn)。提供者可以是Java平臺(tái)的JMS實(shí)現(xiàn),也可以是非Java平臺(tái)的面向消息中間件的適配器。JMS服務(wù)提供者實(shí)現(xiàn)消息隊(duì)列和通知,同時(shí)實(shí)現(xiàn)消息管理API。JMS已經(jīng)是J2EE API的一部分了,J2EE服務(wù)器提供JMS服務(wù)。
2、JMS客戶
生產(chǎn)或消費(fèi)基于消息的Java的應(yīng)用程序或?qū)ο蟆?/p>
3、JMS生產(chǎn)者
創(chuàng)建并發(fā)送消息的JMS客戶。
4、JMS消費(fèi)者
接收消息的JMS客戶。
5、JMS消息
包括可以在JMS客戶之間傳遞數(shù)據(jù)的對(duì)象。消息是服務(wù)提供者和客戶端之間傳遞信息所使用信息單元。JMS消息由以下三部分組成:
- 消息頭(header)—JMS消息頭包含許多字段,它們是消息發(fā)送后由JMS提供者或消息發(fā)送者產(chǎn)生的,用來(lái)表示消息、設(shè)置優(yōu)先權(quán)和失效時(shí)間等等,并且為消息確定路由。
- 屬性(property)—用來(lái)添加刪除消息頭以外的附加消息。
- 消息體(body)—JMS中定義了5種消息體:ByteMessage、MapMessage、ObjectMessage、StreamMessage和TextMessage。
6、JMS隊(duì)列
一個(gè)容納那些被發(fā)送的等待閱讀的消息的區(qū)域。與隊(duì)列名字所暗示的意思不同,消息的接受順序并不一定要與消息的發(fā)送順序相同。一旦一個(gè)消息被閱讀,該消息將被從隊(duì)列中移走。
7、JMS主題
一種支持發(fā)送消息給多個(gè)訂閱者的機(jī)制。
三、JMS的五種消息類型
JMS1.1規(guī)范中規(guī)定了五種JMS類型:ByteMessage、MapMessage、ObjectMessage、StreamMessage和TextMessage。下面我們來(lái)逐個(gè)介紹:
1.創(chuàng)建一個(gè)TextMessage
TextMessage message = session.createTextMessage(“test”);
或
message.setText(“test”);
2.解包一個(gè)TextMessage,去解包一個(gè)TextMessage類型的消息,客戶端可以使用Message.getText方法:
TextMessage message = (TextMessage) consumer.receive();
String text=message.getText();
3.創(chuàng)建一個(gè)BytesMessage
byte[] stockData;
BytesMessage message= session.createBytesMessage();
message.writeBytes(stockData);
4.解包一個(gè)BytesMessage,當(dāng)接收到一個(gè)ByteMessage時(shí),可以使用下面的方式來(lái)解包:
byte[] stockInfo;
int length;
length = message.readBytes(stockData);
消息體被拷貝到字節(jié)數(shù)組,客戶端程序可以讀取這個(gè)樹組來(lái)解釋數(shù)據(jù)。
5.創(chuàng)建一個(gè)MapMessage
MapMessage message;
message = session.createMapMessage();
//其他代碼
message.setString(“Name”, “CN-Java”);
message.setDouble(“Value”, stockValue);
message.setLong(“Time”, stockTime);
message.setDouble(“Diff”, stockDiff);
message.setString(“Info”, “Recent server announcement causes market interest”);
6.解包一個(gè)MapMessage
stockName = message.getString(“Name”);
stockDiff = message.getDouble(“Diff”);
stockValue = message.getDouble(“Value”);
stockTime = message.getLong(“Time”);
如果你想得到整個(gè)元素的列表,可以使用MapMessage.getMapNames方法來(lái)獲得。
7.創(chuàng)建一個(gè)StreamMessage
和MapMessage相似,一個(gè)應(yīng)用程序可以按序列發(fā)送多個(gè)字段到一個(gè)消息中,這些字段都是原始類型的,要做這些,你可以使用一個(gè)StreamMessage,
message.writeString(stockName);
message.writeDouble(stockValue);
message.writeLong(stockTime);
message.writeDouble(stockDiff);
message.writeString(stockInfo);
8.解包一個(gè)StreamMessage
StreamMessage中的元素必須按照被寫入的順序讀出:
stockName = message.readString();
stockValue = message.readDouble();
stockTime = message.readLong();
stockDiff = message.readDouble();
stockInfo = message.readString();
9.創(chuàng)建一個(gè)ObjectMessage
ObjectMessage message;
message = session.createObjectMessage();
message.setObject(stockObject);
10.解包ObjectMessage
去解包ObjectMessage,使用ObjectMessage.getObject得到對(duì)象,一但對(duì)象被取出來(lái),客戶端程序使用Java造型語(yǔ)句將對(duì)象還原成原始對(duì)象。
StockObject stockObject;
stockObject = (StockObject)message.getObject();
四、JMS對(duì)象模型和應(yīng)用程序接口
JMS對(duì)象模型包含如下幾個(gè)要素:
1.連接工廠。連接工廠(ConnectionFactory)是由管理員創(chuàng)建,并綁定到JNDI樹中。客戶端使用JNDI查找連接工廠,然后利用連接工廠創(chuàng)建一個(gè)JMS連接。
2.JMS連接。JMS連接(Connection)表示JMS客戶端和服務(wù)器端之間的一個(gè)活動(dòng)的連接,是由客戶端通過(guò)調(diào)用連接工廠的方法建立的。
3.JMS會(huì)話。JMS會(huì)話(Session)表示JMS客戶與JMS服務(wù)器之間的會(huì)話狀態(tài)。JMS會(huì)話建立在JMS連接上,表示客戶與服務(wù)器之間的一個(gè)會(huì)話線程。
4.JMS目的。JMS目的(Destination),又稱為消息隊(duì)列,是實(shí)際的消息源。
5.JMS生產(chǎn)者和消費(fèi)者。
生產(chǎn)者(Message Producer)和消費(fèi)者(Message Consumer)對(duì)象由Session對(duì)象創(chuàng)建,用于發(fā)送和接收消息。
6.JMS消息
通常有兩種類型:
① 點(diǎn)對(duì)點(diǎn)(Point-to-Point)。在點(diǎn)對(duì)點(diǎn)的消息系統(tǒng)中,消息分發(fā)給一個(gè)單獨(dú)的使用者。點(diǎn)對(duì)點(diǎn)消息往往與隊(duì)列(javax.jms.Queue)相關(guān)聯(lián)。
② 發(fā)布/訂閱(Publish/Subscribe)。發(fā)布/訂閱消息系統(tǒng)支持一個(gè)事件驅(qū)動(dòng)模型,消息生產(chǎn)者和消費(fèi)者都參與消息的傳遞。生產(chǎn)者發(fā)布事件,而使用者訂閱感興趣的事件,并使用事件。該類型消息一般與特定的主題(javax.jms.Topic)關(guān)聯(lián)。
應(yīng)用程序接口:
ConnectionFactory 接口(連接工廠)
??????用戶用來(lái)創(chuàng)建到JMS提供者的連接的被管對(duì)象。JMS客戶通過(guò)可移植的接口訪問(wèn)連接,這樣當(dāng)下層的實(shí)現(xiàn)改變時(shí),代碼不需要進(jìn)行修改。管理員在JNDI名字空間中配置連接工廠,這樣,JMS客戶才能夠查找到它們。根據(jù)消息類型的不同,用戶將使用隊(duì)列連接工廠,或者主題連接工廠。
Connection 接口(連接)
??????連接代表了應(yīng)用程序和消息服務(wù)器之間的通信鏈路。在獲得了連接工廠后,就可以創(chuàng)建一個(gè)與JMS提供者的連接。根據(jù)不同的連接類型,連接允許用戶創(chuàng)建會(huì)話,以發(fā)送和接收隊(duì)列和主題到目標(biāo)。
Destination 接口(目標(biāo))
??????目標(biāo)是一個(gè)包裝了消息目標(biāo)標(biāo)識(shí)符的被管對(duì)象,消息目標(biāo)是指消息發(fā)布和接收的地點(diǎn),或者是隊(duì)列,或者是主題。JMS管理員創(chuàng)建這些對(duì)象,然后用戶通過(guò)JNDI發(fā)現(xiàn)它們。和連接工廠一樣,管理員可以創(chuàng)建兩種類型的目標(biāo),點(diǎn)對(duì)點(diǎn)模型的隊(duì)列,以及發(fā)布者/訂閱者模型的主題。
Session 接口(會(huì)話)
??????表示一個(gè)單線程的上下文,用于發(fā)送和接收消息。由于會(huì)話是單線程的,所以消息是連續(xù)的,就是說(shuō)消息是按照發(fā)送的順序一個(gè)一個(gè)接收的。會(huì)話的好處是它支持事務(wù)。如果用戶選擇了事務(wù)支持,會(huì)話上下文將保存一組消息,直到事務(wù)被提交才發(fā)送這些消息。在提交事務(wù)之前,用戶可以使用回滾操作取消這些消息。一個(gè)會(huì)話允許用戶創(chuàng)建消息,生產(chǎn)者來(lái)發(fā)送消息,消費(fèi)者來(lái)接收消息。
MessageConsumer 接口(消息消費(fèi)者)
??????由會(huì)話創(chuàng)建的對(duì)象,用于接收發(fā)送到目標(biāo)的消息。消費(fèi)者可以同步地(阻塞模式),或(非阻塞)接收隊(duì)列和主題類型的消息。
MessageProducer 接口(消息生產(chǎn)者)
??????由會(huì)話創(chuàng)建的對(duì)象,用于發(fā)送消息到目標(biāo)。用戶可以創(chuàng)建某個(gè)目標(biāo)的發(fā)送者,也可以創(chuàng)建一個(gè)通用的發(fā)送者,在發(fā)送消息時(shí)指定目標(biāo)。
Message 接口(消息)
??????是在消費(fèi)者和生產(chǎn)者之間傳送的對(duì)象,也就是說(shuō)從一個(gè)應(yīng)用程序傳送到另一個(gè)應(yīng)用程序。
五、JMS通信方式
JMS通信方式分為點(diǎn)對(duì)點(diǎn)通信和發(fā)布/訂閱方式
1.點(diǎn)對(duì)點(diǎn)方式(point-to-point)
??????點(diǎn)對(duì)點(diǎn)的消息發(fā)送方式主要建立在 Message Queue,Sender,reciever上,Message Queue 存貯消息,Sender 發(fā)送消息,receive接收消息.具體點(diǎn)就是Sender Client發(fā)送Message Queue ,而 receiver Cliernt從Queue中接收消息和”發(fā)送消息已接受”到Quere,確認(rèn)消息接收。
??????消息發(fā)送客戶端與接收客戶端沒(méi)有時(shí)間上的依賴,發(fā)送客戶端可以在任何時(shí)刻發(fā)送信息到Queue,而不需要知道接收客戶端是不是在運(yùn)行 。也就是說(shuō),點(diǎn)對(duì)點(diǎn)的方式下,一個(gè)生產(chǎn)者向一個(gè)特定的隊(duì)列發(fā)布消息,一個(gè)消費(fèi)者從該隊(duì)列中讀取消息。這里,生產(chǎn)者知道消費(fèi)者的隊(duì)列,并直接將消息發(fā)送到消費(fèi)者的隊(duì)列。可以概括為:只有一個(gè)消費(fèi)者將獲得消息,生產(chǎn)者不需要在接收者消費(fèi)該消息期間處于運(yùn)行狀態(tài),接收者也同樣不需要在消息發(fā)送時(shí)處于運(yùn)行狀態(tài),每一個(gè)成功處理的消息都由接收者簽收。
2.發(fā)布/訂閱 方式(publish/subscriber Messaging)
??????發(fā)布/訂閱方式用于多個(gè)接收端的方式。作為發(fā)布訂閱的方式,可能存在多個(gè)接收端,并且接收端與發(fā)送端存在時(shí)間上的依賴。一個(gè)接收端只能接收它創(chuàng)建以后發(fā)送端發(fā)送的信息。作為subscriber ,在接收消息時(shí)有兩種方法,destination的receive方法,和實(shí)現(xiàn)message listener 接口的onMessage 方法。
??????發(fā)布者/訂閱者方式支持向一個(gè)特定的消息主題發(fā)布消息。0或多個(gè)訂閱者可能對(duì)接收來(lái)自特定消息主題的消息感興趣。在這種方式下,發(fā)布者和訂閱者彼此不知道對(duì)方。這種方式好比是匿名公告板。這種方式被概括為:
??????多個(gè)消費(fèi)者可以獲得消息。在發(fā)布者和訂閱者之間存在時(shí)間依賴性。發(fā)布者需要建立一個(gè)訂閱(subscription),以便客戶能夠訂閱。訂閱者必須保持持續(xù)的活動(dòng)狀態(tài)以接收消息,除非訂閱者建立了持久的訂閱。在那種情況下,在訂閱者未連接時(shí)發(fā)布的消息將在訂閱者重新連接時(shí)重新發(fā)布。
六、JMS消息傳遞方式
??????JMS有兩種傳遞消息的方式。標(biāo)記為NON_PERSISTENT的消息最多投遞一次,而標(biāo)記為PERSISTENT的消息將使用暫存后再轉(zhuǎn)送的機(jī)理投遞。如果一個(gè)JMS服務(wù)離線,那么持久性消息不會(huì)丟失但是得等到這個(gè)服務(wù)恢復(fù)聯(lián)機(jī)時(shí)才會(huì)被傳遞。所以默認(rèn)的消息傳遞方式是非持久性的。即使使用非持久性消息可能降低內(nèi)務(wù)和需要的存儲(chǔ)器,并且這種傳遞方式只有當(dāng)你不需要接收所有的消息時(shí)才使用。
??????雖然JMS規(guī)范并不需要JMS供應(yīng)商實(shí)現(xiàn)消息的優(yōu)先級(jí)路線,但是它需要遞送加快的消息優(yōu)先于普通級(jí)別的消息。JMS定義了從0到9的優(yōu)先級(jí)路線級(jí)別,0是最低的優(yōu)先級(jí)而9則是最高的。更特殊的是0到4是正常優(yōu)先級(jí)的變化幅度,而5到9是加快的優(yōu)先級(jí)的變化幅度。舉例來(lái)說(shuō):
或
queueSender.send(message,DeliveryMode.PERSISTENT, 8, 10000);//P2P??????這個(gè)代碼片斷,有兩種消息模型,映射遞送方式是持久的,優(yōu)先級(jí)為加快型,生存周期是10000 (以毫秒度量)。如果生存周期設(shè)置為零,這則消息將永遠(yuǎn)不會(huì)過(guò)期。當(dāng)消息需要時(shí)間限制否則將使其無(wú)效時(shí),設(shè)置生存周期是有用的。
七、JMS提供者
??????要使用Java消息服務(wù),你必須要有一個(gè)JMS提供者,管理會(huì)話和隊(duì)列。既有開源的提供者也有專有的提供者。
開源的提供者包括:
Apache ActiveMQ
JBoss 社區(qū)所研發(fā)的 HornetQ
Joram
Coridan的MantaRay
The OpenJMS Group的OpenJMS
專有的提供者包括:
BEA的BEA WebLogic Server JMS
TIBCO Software的EMS
GigaSpaces Technologies的GigaSpaces
Softwired 2006的iBus
IONA Technologies的IONA JMS
SeeBeyond的IQManager(2005年8月被Sun Microsystems并購(gòu))
webMethods的JMS+ -
my-channels的Nirvana
Sonic Software的SonicMQ
SwiftMQ的SwiftMQ
IBM的WebSphere MQ
總結(jié)
以上是生活随笔為你收集整理的【JMS】JMS详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: InetAddressSocket使用总
- 下一篇: 【Spring源码】从源码实现的角度解析