rednight

          0x2B|~0x2B,That's not a question,Just do it.
          posts - 32, comments - 14, trackbacks - 0, articles - 0

          消息中間件和JMS

          Posted on 2007-04-11 16:41 rednight 閱讀(345) 評(píng)論(0)  編輯  收藏

          當(dāng)前,CORBA、DCOM、RMI等RPC中間件技術(shù)已廣泛應(yīng)用于各個(gè)領(lǐng)域。但是面對(duì)規(guī)模和復(fù)雜度都越來越高的分布式系統(tǒng),這些技術(shù)也顯示出其局限性:(1)同步通信:客戶發(fā)出調(diào)用后,必須等待服務(wù)對(duì)象完成處理并返回結(jié)果后才能繼續(xù)執(zhí)行;(2)客戶和服務(wù)對(duì)象的生命周期緊密耦合:客戶進(jìn)程和服務(wù)對(duì)象進(jìn)程都必須正常運(yùn)行;如果由于服務(wù)對(duì)象崩潰或者網(wǎng)絡(luò)故障導(dǎo)致客戶的請(qǐng)求不可達(dá),客戶會(huì)接收到異常;(3)點(diǎn)對(duì)點(diǎn)通信:客戶的一次調(diào)用只發(fā)送給某個(gè)單獨(dú)的目標(biāo)對(duì)象。
             面向消息的中間件(Message Oriented Middleware,MOM)較好的解決了以上問題。發(fā)送者將消息發(fā)送給消息服務(wù)器,消息服務(wù)器將消息存放在若干隊(duì)列中,在合適的時(shí)候再將消息轉(zhuǎn)發(fā)給接收者。這種模式下,發(fā)送和接收是異步的,發(fā)送者無需等待;二者的生命周期未必相同:發(fā)送消息的時(shí)候接收者不一定運(yùn)行,接收消息的時(shí)候發(fā)送者也不一定運(yùn)行;一對(duì)多通信:對(duì)于一個(gè)消息可以有多個(gè)接收者。
             已有的MOM系統(tǒng)包括IBM的MQSeries、Microsoft的MSMQ和BEA的MessageQ等。由于沒有一個(gè)通用的標(biāo)準(zhǔn),這些系統(tǒng)很難實(shí)現(xiàn)互操作和無縫連接。Java Message Service(JMS)是SUN提出的旨在統(tǒng)一各種MOM系統(tǒng)接口的規(guī)范,它包含點(diǎn)對(duì)點(diǎn)(Point to Point,PTP)和發(fā)布/訂閱(Publish/Subscribe,pub/sub)兩種消息模型,提供可靠消息傳輸、事務(wù)和消息過濾等機(jī)制。

          1.JMS
             JAVA 消息服務(wù)(JMS)定義了Java 中訪問消息中間件的接口。JMS 只是接口,并沒有給予實(shí)現(xiàn),實(shí)現(xiàn)JMS 接口的消息中間件稱為JMS Provider,iLink實(shí)現(xiàn)了JMS接口,用戶可以通過使用JMS接口,在iLink中進(jìn)行JMS編程。 iLink支持JMS1.0.2版本。

          2.JMS接口描述
             JMS 支持兩種消息類型PTP 和Pub/Sub,分別稱作:PTP Domain 和Pub/Sub Domain,這兩種接口都繼承統(tǒng)一的JMS父接口,JMS 主要接口如下所示:

          MS父接口

          PTP

          Pub/Sub

          ConnectionFactory

          QueueConnectionFactory

          TopicConnectionFactory

          Connection

          QueueConnection

          TopicConnection

          Destination

          Queue

          Topic

          Session

          QueueSession

          TopicSession

          MessageProducer

          QueueSender

          TopicPublisher

          MessageConsumer

          QueueReceiver,QueueBrowse r

          TopicSubscriber

           

           

           

                            
             ConnectionFactory :連接工廠,JMS 用它創(chuàng)建連接
             Connection :JMS 客戶端到JMS Provider 的連接
             Destination :消息的目的地
             Session: 一個(gè)發(fā)送或接收消息的線程
             MessageProducer: 由Session 對(duì)象創(chuàng)建的用來發(fā)送消息的對(duì)象
             MessageConsumer: 由Session 對(duì)象創(chuàng)建的用來接收消息的對(duì)象

          3.JMS消息模型
          JMS 消息由以下幾部分組成:消息頭,屬性,消息體。
            
          3.1 消息頭(Header) - 消息頭包含消息的識(shí)別信息和路由信息,消息頭包含一些標(biāo)準(zhǔn)的屬性如:JMSDestination,JMSMessageID 等。

           消息頭

           由誰設(shè)置

          JMSDestination

          send 或 publish 方法

          JMSDeliveryMode

          send 或 publish 方法

          JMSExpiration

          send 或 publish 方法

          JMSPriority

          send 或 publish 方法

          JMSMessageID

          send 或 publish 方法

          JMSTimestamp

          send 或 publish 方法

          JMSCorrelationID

          客戶

          JMSReplyTo

          客戶

          JMSType

          客戶

          JMSRedelivered

          JMS Provider

           

           

                  
           

           

           

                


          3.2 屬性(Properties)
          - 除了消息頭中定義好的標(biāo)準(zhǔn)屬性外,JMS 提供一種機(jī)制增加新屬性到消息頭 中,這種新屬性包含以下幾種:
             1. 應(yīng)用需要用到的屬性;
             2. 消息頭中原有的一些可選屬性;
             3. JMS Provider 需要用到的屬性。
             標(biāo)準(zhǔn)的JMS 消息頭包含以下屬性:

          JMSDestination

          消息發(fā)送的目的地

          JMSDeliveryMode

          傳遞模式, 有兩種模式: PERSISTENT 和NON_PERSISTENT,PERSISTENT 表示該消息一定要被送到目的地,否則會(huì)導(dǎo)致應(yīng)用錯(cuò)誤。NON_PERSISTENT 表示偶然丟失該消息是被允許的,這兩種模式使開發(fā)者可以在消息傳遞的可靠性和吞吐量之間找到平衡點(diǎn)。

          JMSMessageID

          唯一識(shí)別每個(gè)消息的標(biāo)識(shí),由JMS Provider 產(chǎn)生。

          JMSTimestamp

          一個(gè)消息被提交給JMS Provider 到消息被發(fā)出的時(shí)間。

          JMSCorrelationID

          用來連接到另外一個(gè)消息,典型的應(yīng)用是在回復(fù)消息中連接到原消息。

          JMSReplyTo

          提供本消息回復(fù)消息的目的地址

          JMSRedelivered

          如果一個(gè)客戶端收到一個(gè)設(shè)置了JMSRedelivered 屬性的消息,則表示可能該客戶端曾經(jīng)在早些時(shí)候收到過該消息,但并沒有簽收(acknowledged)。

          JMSType

          消息類型的識(shí)別符。

          JMSExpiration

          消息過期時(shí)間,等于QueueSender 的send 方法中的timeToLive 值或TopicPublisher 的publish 方法中的timeToLive 值加上發(fā)送時(shí)刻的GMT 時(shí)間值。如果timeToLive值等于零,則JMSExpiration 被設(shè)為零,表示該消息永不過期。如果發(fā)送后,在消息過期時(shí)間之后消息還沒有被發(fā)送到目的地,則該消息被清除。

          JMSPriority

          消息優(yōu)先級(jí),從0-9 十個(gè)級(jí)別,0-4 是普通消息,5-9 是加急消息。JMS 不要求JMS Provider 嚴(yán)格按照這十個(gè)優(yōu)先級(jí)發(fā)送消息,但必須保證加急消息要先于普通消息到達(dá)。

           

           

           

           

           

           

           

           

           

           



          3.3 消息體(Body) - JMS API 定義了5種消息體格式,也叫消息類型,你可以使用不同形式發(fā)送接收 數(shù)據(jù)并可以兼容現(xiàn)有的消息格式,下面描述這5種類型:

          消息類型

          消息體

          TextMessage

          java.lang.String對(duì)象,如xml文件內(nèi)容

          MapMessage

          名/值對(duì)的集合,名是String對(duì)象,值類型可以是Java任何基本類型

          BytesMessage

          字節(jié)流

          StreamMessage

          Java中的輸入輸出流

          ObjectMessage

          Java中的可序列化對(duì)象

          Message

          沒有消息體,只有消息頭和屬性













          下例演示創(chuàng)建并發(fā)送一個(gè)TextMessage到一個(gè)隊(duì)列:
          TextMessage message = queueSession.createTextMessage();
          message.setText(msg_text); // msg_text is a String
          queueSender.send(message);

          下例演示接收消息并轉(zhuǎn)換為合適的消息類型:
          Message m = queueReceiver.receive();
          if (m instanceof TextMessage) {
           TextMessage message = (TextMessage) m;
           System.out.println("Reading message: " + message.getText());
          } else {
           // Handle error
          }

          4. 消息的同步異步接收
             消息的同步接收是指客戶端主動(dòng)去接收消息,JMS 客戶端可以采用MessageConsumer 的receive方法去接收下一個(gè)消息。
             消息的異步接收是指當(dāng)消息到達(dá)時(shí),主動(dòng)通知客戶端。JMS 客戶端可以通過注冊(cè)一個(gè)實(shí) 現(xiàn)MessageListener 接口的對(duì)象到MessageConsumer,這樣,每當(dāng)消息到達(dá)時(shí),JMS Provider 會(huì)調(diào)用MessageListener中的onMessage 方法。

          5. PTP模型
          PTP(Point-to-Point)模型是基于隊(duì)列的,發(fā)送方發(fā)消息到隊(duì)列,接收方從隊(duì)列接收消息,隊(duì)列的存在使得消息的異步傳輸成為可能。和郵件系統(tǒng)中的郵箱一樣,隊(duì)列可以包含各種消息,JMS Provider 提 供工具管理隊(duì)列的創(chuàng)建、刪除。JMS PTP 模型定義了客戶端如何向隊(duì)列發(fā)送消息,從隊(duì)列接收消息,瀏覽隊(duì)列中的消息。
             下面描述JMS PTP 模型中的主要概念和對(duì)象:

          名稱

          描述

          Queue

          由JMS Provider 管理,隊(duì)列由隊(duì)列名識(shí)別,客戶端可以通過JNDI 接口用隊(duì)列名得到一個(gè)隊(duì)列對(duì)象。

          TemporaryQueue

          由QueueConnection 創(chuàng)建,而且只能由創(chuàng)建它的QueueConnection 使用。

          QueueConnectionFactory

          客戶端用QueueConnectionFactory 創(chuàng)建QueueConnection 對(duì)象。

          QueueConnection

          一個(gè)到JMS PTP provider 的連接,客戶端可以用QueueConnection 創(chuàng)建QueueSession 來發(fā)送和接收消息。

          QueueSession

          提供一些方法創(chuàng)建QueueReceiver 、QueueSender、QueueBrowser 和TemporaryQueue。如果在QueueSession 關(guān)閉時(shí),有一些消息已經(jīng)被收到,但還沒有被簽收(acknowledged),那么,當(dāng)接收者下次連接到相同的隊(duì)列時(shí),這些消息還會(huì)被再次接收。

          QueueReceiver

          客戶端用QueueReceiver 接收隊(duì)列中的消息,如果用戶在QueueReceiver 中設(shè)定了消息選擇條件,那么不符合條件的消息會(huì)留在隊(duì)列中,不會(huì)被接收到。

          QueueSender

          客戶端用QueueSender 發(fā)送消息到隊(duì)列。

          QueueBrowser

          客戶端可以QueueBrowser 瀏覽隊(duì)列中的消息,但不會(huì)收走消息。

          QueueRequestor

          JMS 提供QueueRequestor 類簡(jiǎn)化消息的收發(fā)過程。QueueRequestor 的構(gòu)造函數(shù)有兩個(gè)參數(shù):QueueSession 和queue,QueueRequestor 通過創(chuàng)建一個(gè)臨時(shí)隊(duì)列來完成最終的收發(fā)消息請(qǐng)求。

          可靠性(Reliability)

          隊(duì)列可以長(zhǎng)久地保存消息直到接收者收到消息。接收者不需要因?yàn)閾?dān)心消息會(huì)丟失而時(shí)刻和隊(duì)列保持激活的連接狀態(tài),充分體現(xiàn)了異步傳輸模式的優(yōu)勢(shì)。



                        
                    
            
           

           

           

           

           

           

           

           

           


          6. PUB/SUB模型
          JMS Pub/Sub 模型定義了如何向一個(gè)內(nèi)容節(jié)點(diǎn)發(fā)布和訂閱消息,這些節(jié)點(diǎn)被稱作主題(topic)。
             主題可以被認(rèn)為是消息的傳輸中介,發(fā)布者(publisher)發(fā)布消息到主題,訂閱者(subscribe)從主題訂閱消息。主題使得消息訂閱者和消息發(fā)布者保持互相獨(dú)立,不需要接觸即可保證消息的傳送。
             下面描述JMS Pub/Sub 模型中的主要概念和對(duì)象:

          名稱

          描述

          訂閱(subscription)

          消息訂閱分為非持久訂閱(non-durable subscription)和持久訂閱(durable subscrip-tion),非持久訂閱只有當(dāng)客戶端處于激活狀態(tài),也就是和JMS Provider 保持連接狀態(tài)才能收到發(fā)送到某個(gè)主題的消息,而當(dāng)客戶端處于離線狀態(tài),這個(gè)時(shí)間段發(fā)到主題的消息將會(huì)丟失,永遠(yuǎn)不會(huì)收到。持久訂閱時(shí),客戶端向JMS 注冊(cè)一個(gè)識(shí)別自己身份的ID,當(dāng)這個(gè)客戶端處于離線時(shí),JMS Provider 會(huì)為這個(gè)ID 保存所有發(fā)送到主題的消息,當(dāng)客戶再次連接到JMS Provider時(shí),會(huì)根據(jù)自己的ID 得到所有當(dāng)自己處于離線時(shí)發(fā)送到主題的消息。

          Topic

          主題由JMS Provider 管理,主題由主題名識(shí)別,客戶端可以通過JNDI 接口用主題名得到一個(gè)主題對(duì)象。JMS 沒有給出主題的組織和層次結(jié)構(gòu)的定義,由JMS Provider 自己定義。

          TemporaryTopic

          臨時(shí)主題由TopicConnection 創(chuàng)建,而且只能由創(chuàng)建它的TopicConnection 使用。臨時(shí)主題不能提供持久訂閱功能。

          TopicConnectionFactory

          客戶端用TopicConnectionFactory 創(chuàng)建TopicConnection 對(duì)象。

          TopicConnection

          TopicConnection 是一個(gè)到JMS Pub/Sub provider 的連接,客戶端可以用TopicConnection創(chuàng)建TopicSession 來發(fā)布和訂閱消息。

          TopicSession

          TopicSession 提供一些方法創(chuàng)建TopicPublisher、TopicSubscriber、TemporaryTopic 。它還提供unsubscribe 方法取消消息的持久訂閱。

          TopicPublisher

          客戶端用TopicPublisher 發(fā)布消息到主題。

          TopicSubscriber

          客戶端用TopicSubscriber 接收發(fā)布到主題上的消息。可以在TopicSubscriber 中設(shè)置消息過濾功能,這樣,不符合要求的消息不會(huì)被接收。

          Durable TopicSubscriber

          如果一個(gè)客戶端需要持久訂閱消息,可以使用Durable TopicSubscriber,TopSession 提供一個(gè)方法createDurableSubscriber創(chuàng)建Durable TopicSubscriber 對(duì)象。

          恢復(fù)和重新派送(Recovery and Redelivery)

          非持久訂閱狀態(tài)下,不能恢復(fù)或重新派送一個(gè)未簽收的消息。只有持久訂閱才能恢復(fù)或重新派送一個(gè)未簽收的消息。

          TopicRequestor

          JMS 提供TopicRequestor 類簡(jiǎn)化消息的收發(fā)過程。TopicRequestor 的構(gòu)造函數(shù)有兩個(gè)參數(shù):TopicSession 和topic。TopicRequestor 通過創(chuàng)建一個(gè)臨時(shí)主題來完成最終的發(fā)布和接收消息請(qǐng)求。

          可靠性(Reliability)

          當(dāng)所有的消息必須被接收,則用持久訂閱模式。當(dāng)丟失消息能夠被容忍,則用非持久訂閱模式。

           

           

           

           

           

           

           


           

           


           
           
           
           
           
           
           
           
           




          7. 開發(fā)JMS的步驟
             廣義上說,一個(gè)JMS 應(yīng)用是幾個(gè)JMS 客戶端交換消息,開發(fā)JMS 客戶端應(yīng)用由以下幾步構(gòu)成:
          用JNDI 得到ConnectionFactory 對(duì)象;
          用JNDI 得到目標(biāo)隊(duì)列或主題對(duì)象,即Destination 對(duì)象;
          用ConnectionFactory 創(chuàng)建Connection 對(duì)象;
          用Connection 對(duì)象創(chuàng)建一個(gè)或多個(gè)JMS Session;
          用Session 和Destination 創(chuàng)建MessageProducer 和MessageConsumer;
          通知Connection 開始傳遞消息。


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 保康县| 安西县| 高淳县| 抚宁县| 高唐县| 沙田区| 汽车| 丹凤县| 疏勒县| 扶绥县| 凤冈县| 阳信县| 庆元县| 博客| 平远县| 南昌县| 迭部县| 邳州市| 镇康县| 中阳县| 高雄县| 肥西县| 大悟县| 乌什县| 兴和县| 永州市| 山阳县| 泰来县| 南通市| 琼海市| 蓝山县| 盐亭县| 达孜县| 永平县| 冕宁县| 昭平县| 安远县| 江阴市| 本溪| 马关县| 瑞昌市|