- 論壇徽章:
- 0
|
最近在學(xué)習(xí)JMS,粘添一下SUN的入門問題。
一般問題
問. 什么是 Java 消息服務(wù)?
答: Java 消息服務(wù)(Java Message Service,JMS) API 是一個用于訪問企業(yè)消息傳遞系統(tǒng)的 API。是 Java 2 Platform, Enterprise(J2EE)的一部分。
Java 消息服務(wù)使得編寫那些需要異步發(fā)送及接收重要業(yè)務(wù)數(shù)據(jù)和事件的業(yè)務(wù)應(yīng)用變得容易。
Java 消息服務(wù)定義了一個公共的企業(yè)消息傳遞 API,該 API 設(shè)計來被大范圍的企業(yè)消息傳遞產(chǎn)品容易而有效地支持。
Java 消息服務(wù)不僅支持消息隊列,還支持消息傳遞的發(fā)布/訂閱模式。
問. Java 消息服務(wù)是另一種郵件 API 嗎?
答: 不是。術(shù)語“消息傳遞”在計算機領(lǐng)域的定義很廣。它被用來描述不同的操作系統(tǒng)概念,用于描述電子郵件和傳真系統(tǒng);如果使用了 JMS API,它被用來描述企業(yè)應(yīng)用之間的異步通信。
JMS 消息是指由企業(yè)應(yīng)用(而不是人)消費的異步請求、報告或事件。它們包含了協(xié)同這些系統(tǒng)所需的重要信息,包含了描述特定業(yè)務(wù)活動的精確格式化的數(shù)據(jù)。通過這些消息的交換,每個應(yīng)用可以跟蹤企業(yè)的進展。
問. Java 消息服務(wù)是一種產(chǎn)品嗎?
答: 不是,Java 消息服務(wù)是一個用于企業(yè)消息傳遞的公共 API 的規(guī)范,使用它需要一個由企業(yè)消息傳遞供應(yīng)商提供的 JMS 提供者。
問. 可從哪里獲得 Java 消息服務(wù)規(guī)范?
答: Java 消息服務(wù) 1.0.2 規(guī)范可從
![]()
http://java.sun.com/products/jms/docs.html
處獲得。在線的 JMS API 文檔也可在這個鏈接地址中找到。
問. 誰與 SUN 公司一起制定了 Java 消息服務(wù) 1.0.2 規(guī)范?
答: 起初有眾多重要的行業(yè)參與者與 SUN 公司一起共同制定了 Java 消息服務(wù)規(guī)范的初稿。另外,在為期 3 個月的公眾評審期間,收到了來自其他公司、政府和教育組織以及其他機構(gòu)的許多建議。
問. Java 消息服務(wù)有何引人注目的?
答: Java 消息服務(wù)引人注目的原因是:
它是第一個得到廣泛行業(yè)支持的企業(yè)消息傳遞 API。
通過提供適應(yīng)廣泛企業(yè)消息傳遞系統(tǒng)的標準消息傳遞概念和約定,它簡化了企業(yè)應(yīng)用的開發(fā)。
它利用現(xiàn)有的,經(jīng)過企業(yè)驗證的消息傳遞系統(tǒng)。
問. 開發(fā)人員為何應(yīng)該使用 Java 消息服務(wù)?
答: 因為 Java 消息服務(wù)能使下面的工作變得簡單:
編寫可移植的,基于消息的業(yè)務(wù)應(yīng)用。
通過加入新的能夠與現(xiàn)有非 JMS 客戶端完全協(xié)作的 JMS 客戶端,以擴展現(xiàn)有的基于消息的應(yīng)用。
問. 為了學(xué)習(xí)使用 Java 消息服務(wù),程序員需要具備什么?
答: 基于消息的應(yīng)用和基于遠程過程調(diào)用的應(yīng)用是根本不同的。一旦開發(fā)人員理解了如何最好地使用這兩個技術(shù), JMS API 就使得編寫基于消息的應(yīng)用跟學(xué)習(xí)幾個附加接口一樣容易。
問. Java 消息服務(wù)和企業(yè) JavaBeans 組件有何關(guān)系?
答: 自從 J2EE 1.2 版本發(fā)布以來,企業(yè) JavaBeans 組件已經(jīng)能夠使用 JMS API 來同步地發(fā)送和接收企業(yè)消息。J2EE 1.3 版本現(xiàn)在已可獲得,它提供了一種新的允許企業(yè)應(yīng)用異步地接收消息的企業(yè) Bean,即消息驅(qū)動 Bean。
問. Java 消息服務(wù) API 與 Java 命名和目錄接口(JNDI) API 之間有何關(guān)系?
答:
跟其他 Java 企業(yè) API 一樣,JMS API 使用 JNDI API 來進行管理。JMS API 將
ConnectionFactories 和 Destinations 定義為被管理對象,它們被配置并放入到 JNDI 命名的上下文中。然后
JMS 客戶端查找和使用這些預(yù)先配置好的對象。這樣保證了 JMS 應(yīng)用易于部署和管理。
問. Java 消息服務(wù) API 與 Java 數(shù)據(jù)庫連接(JDBC)API 之間有何關(guān)系?
答: JMS 客戶端或許也使用 JDBC API。在同一個事務(wù)中它們可能既使用 JMS API 也使用 JDBC API。大多數(shù)情況下,通過把這些客戶端實現(xiàn)為企業(yè) Bean,JMS 客戶端可自動完成。JMS 客戶端可能也使用 Java 事務(wù) API。
問. Java 消息服務(wù)與 Java 事務(wù) API 及 Java 事務(wù)服務(wù)之間有何關(guān)系?
答:
Java 事務(wù) API (Java Transaction API,JTA) 提供了一個用于劃分分布式事務(wù)的客戶端 API,以及一個用于訪問資
源以能夠參與分布式事務(wù)的 API。JMS 客戶端可能使用 JTA 來劃分分布式事務(wù)。JMS 提供者通過 JTA 可以自如地支持分布式事務(wù)。
Java
事務(wù)服務(wù) (Java Transaction Service,JTS) 能和JMS API一道用來形成分布式的事務(wù),該事務(wù)結(jié)合了消息收發(fā)與數(shù)據(jù)庫
更新以及其他 JTS 能識別的服務(wù)。當 JMS 客戶端在應(yīng)用服務(wù)器(比如 J2EE 服務(wù)器)中運行時,這些服務(wù)應(yīng)該被自動處理;可是, 也有可能需
要 JMS 客戶端去明確編寫它們。
問. 在哪里可以找到 JMS API 討論組?
在
![]()
http://java.sun.com/j2ee/community/forums/index.html
處可找到一個 JMS API 論壇。要加入這個論壇,您必須是 Java Developer Connection 的成員。
問. 為什么 JMS API 發(fā)展成為一種在企業(yè)內(nèi)部組件間提供通信的技術(shù),而不是用于在企業(yè)間通過 Internet 進行企業(yè)-企業(yè)(B2B)的通信?
答: 提供基于 Internet 的 JMS API 消息傳遞的主要問題是,JMS API 供應(yīng)商們必須使用一種共同的通信格式,并且 JMS 規(guī)范必須指定一個路由器-路由器 API。
B2B 消息傳遞是一個重要的領(lǐng)域,有它自己獨特的要求。該領(lǐng)域正被一些不斷涌現(xiàn)的標準所占據(jù),比如電子商務(wù) XML計劃,即 ebXML (參見
![]()
http://www.ebxml.org/),SUN
公司在這一方面起到了積極的作用。現(xiàn)在,ebXML 計劃定義了一個消息傳遞服務(wù) (參見 ebXML Specifications 頁面), 它支
持通過Internet 的 XML 消息傳遞。當前的 ebXML 規(guī)范著重于,通過使用多種傳輸協(xié)議,比如 HTTP、mail 和 FTP,通過
Internet 提供終端間的點到點異步通信。ebXML 還計劃提供發(fā)布/訂閱式的 XML 消息傳遞。Sun 公司和它的合作伙伴正在定義一個新
的 Java API for Messaging,即 JAXM (參見 JSR #000067,
Java APIs for XML Messaging 1.0), 它支持 ebXML 消息服務(wù)規(guī)范。早先版本的 JAXM 可以從
Java Developer Connection 的 The M Project 1.0 Early Access 處得到。
總之, JMS API 是特意設(shè)計為在企業(yè)內(nèi)部使用的,而獨立企業(yè)之間通過 Internet 進行的 XML 消息傳遞將得到 ebXML 計劃和新的支持不同 ebXML 規(guī)范的 Java API(包括 JAXM)的支持。
技術(shù)問題
問. JMS API 需要哪一種 JDK 版本?
答: JMS API 需要 JDK/JRE 1.1.x 或者更高的版本。
問. JMS API 是否提供了一個分布式 Java 事件模型的版本?
答:
一般來講,JMS API 可以被用作通知服務(wù);但是,它沒有定義 Java 事件的分布式版本。一個實現(xiàn)分布式 Java 事件的可選方案是作為
JavaBeans 組件,該組件通過 JMS API 透明地向事件產(chǎn)生 Bean 和事件監(jiān)聽 Bean 分布事件。
問. 為什么有兩個各自分開的 JMS API 域,即點到點和發(fā)布/訂閱,而不合為一個域呢?
答: 即使有許多類似之處,提供獨立的域仍然很重要。這意味著廠商不必被強迫支持不屬于他們的域內(nèi)的設(shè)備,客戶端代碼也更加輕便靈活,因為產(chǎn)品更充分地支持一個域(相對于支持一個合并域中較少定義的子集而言)。
問. 為什么 JMS API 不指定一套 JavaBeans 組件?
答: JMS API 是一個低級的 API, 就像其他低級的 Java API 一樣, 它無助于直接表現(xiàn)為 JavaBeans 組件。
問. JMS API 如何與 CORBA 通知服務(wù)相結(jié)合?
答: 通知服務(wù)為 CORBA 事件服務(wù)增加了過濾功能、傳輸保證語義、持久性連接和事件網(wǎng)絡(luò)的集結(jié)。它從 CORBA 消息服務(wù)(該服務(wù)定義了異步 CORBA 方法調(diào)用)獲得傳輸保證語義。
Java 技術(shù)與 CORBA 很好的結(jié)合在一起。它提供了 Java IDL 和 COS Naming 技術(shù)。另外,OMG 最近定義了 RMI over IIOP。
預(yù)
計大多數(shù) Java 對 IIOP 的使用將通過 RMI。預(yù)計大多數(shù) Java 對 COS Naming 的使用將通過 JNDI API
(Java 命名和目錄服務(wù))。JMS API 是 Java 特定的 API,它設(shè)計位于大范圍現(xiàn)有和未來的面向消息中間件
(Message Oriented Middleware,MOM)系統(tǒng)的上層(正如 JNDI API位于現(xiàn)有命名和目錄服務(wù)的上層一樣)。
問. 為什么 JMS API 不提供端到端的同步消息傳輸和傳輸通知?
答: 作為一個實現(xiàn)可靠應(yīng)用的機制,一些消息傳遞系統(tǒng)提供到目的地的同步傳輸。一些系統(tǒng)為客戶端提供了不同形式的傳輸通知,這樣客戶端就能檢測出被刪除或忽略的消息。這不是由 JMS API 定義的模型。
JMS API
消息傳遞通過一次并且只有一次的 PERSISTENT 消息傳輸語義來提供有保障的傳輸。另外,消息消費者可以通過使用
CLIENT_ACKNOWLEDGE 模式或事務(wù)會話來確?煽康南⑻幚。這樣使用最小的同步實現(xiàn)了可靠的傳輸,這是大多數(shù)廠商和開發(fā)者都喜歡的企
業(yè)消息傳遞模型。
JMS API 沒有定義系統(tǒng)消息(如傳輸通知)的模式。如果應(yīng)用需要消息收到的確認回復(fù),可以定義一個應(yīng)用級的確認消息。
這些問題放到發(fā)布/訂閱應(yīng)用的上下文中考察,將能更清楚地理解。在這個上下文中,同步傳輸和/或系統(tǒng)接收確認對于實現(xiàn)可靠的應(yīng)用并不是一個有效的機制(因為,按照定義,生產(chǎn)者不會,也不想負責(zé)端到端的消息傳輸)。
問. 為什么 JMS API 不提供群體發(fā)送(send-to-list)機制?
答: 當前,JMS API 提供大量的消息傳送選擇;但是,消息在同一時刻只能發(fā)送到一個目的地。
群體發(fā)送的好處是,程序員只需做很少的工作,并且還有 JMS 提供者對發(fā)送同樣的消息到多個目的地的情況進行優(yōu)化的潛力。
群體發(fā)送機制不利的方面是,目的列表在效果上是由客戶端實現(xiàn)并維護的集合。這將增加 JMS 客戶端管理的復(fù)雜度。
不使用提供群體發(fā)送機制的 JMS API,而推薦提供者支持配置代表一個群體的目的。這允許客戶端通過一次發(fā)送便可以到達所有的消費者,同時保證群體被正確地管理。
問. 為什么 JMS API 不提供訂閱通知?如果發(fā)布者能夠察覺到一個主題的訂閱者已經(jīng)存在,它將能抑制非訂閱主題的發(fā)布。
答: 盡管給發(fā)布者提供抑制發(fā)布非訂閱主題的機制可能會帶來一些好處,但是這將增加 JMS API 的復(fù)雜性,并需要附加的提供者開銷,而這些并不與它帶來的好處成正比。相反,JMS 提供者應(yīng)該保證最小化用于處理發(fā)布給非訂閱主題的消息的開銷。
問. 如果消息消費者已經(jīng)關(guān)閉了,該消息還能被確認嗎?
答: 可以。既然消息確認是在會話級處理的,那么在消費者關(guān)閉后,消息確認仍然是相關(guān)的。所有由會話消費的消息按以下兩個例子情況被確認:
// CLIENT_ACKNOWLEDGE session
Message msg1 = topicSubscriber1.receive();
Message msg2 = topicSubscriber2.receive();
topicSubscriber1.close();
msg2.acknowledge();
// transacted session
Message msg1 = queueReceiver.receive();
queueReceiver.close();
session.commit();
在會話被關(guān)閉后,對 Message.acknowledge 或 Session.commit 方法的調(diào)用將拋出IllegalStateException 異常。對于事務(wù)型會話,如果在進行事務(wù)提交之前調(diào)用 close 方法,那么該事務(wù)將被回滾。
注意,為了防止從持久訂閱或隊列重復(fù)投遞消息,一個仍能被會話確認的消息不能被投遞到別的消息消費者。只有當初始收到消息的會話再也不能確認該消息時,此消息才能被投遞到別的消息消費者。
問. 當同一隊列在相同時間有兩個或以上 QueueReceiver 時,JMS API 指定的是什么分發(fā)策略?
答:
當有兩個或以上的 QueueReceiver 同時注冊到某個目的地時,JMS API 并沒有指定消息分發(fā)策略。JMS API 語義上在任何時刻
只說明一個 QueueReceiver。JMS API 并不禁止一個隊列有多個 QueueReceiver;它只是沒有為這種情況定義行為。
問. 在一個會話當中的同一個主題有兩個或以上 TopicSubscriber 時,CLIENT_ACKNOWLEDGE 模式是如何工作的?
答: 從 JMS 1.0.2 規(guī)范第 6.11 節(jié)得知:
一
個 TopicSession 允許為每個目的地創(chuàng)建多個 TopicSubscriber,它將把針對某個目的地的消息投遞到每一個能接收它的
TopicSubscriber。每一個消息的拷貝將被認為是完全獨立的消息。對其中的一個所做的處理將不會影響到其他的拷貝;確認其中一個并不等于確
認其他;一條消息可以馬上被投遞,即使在它之前有其他的拷貝正在等待消費者去處理。
Message.acknowledge 方法是編寫來確認
由會話消費的所有消息的接收。因此,如果msgA 被投遞到同一個會話中的主題訂閱者 TS1 和 TS2,TS1 同步接收 msgA 的拷貝,那么
TS2 也能同步接收 msgA 的拷貝。然而,如果 TS1 接收 msgA 的拷貝,然后 TS2 接收 msgA 的拷貝,TS2 對接收該消息
的確認將確認 TS1 和 TS2 都收到了 msgA 的拷貝,事實上會話接收 TS1 的 msgA 拷貝是在會話接收 TS2 的 msgA 拷貝
之前發(fā)生的。
問. 對于已關(guān)閉的消費者來說,消息的可恢復(fù)性指的是什么?
答: 對于從隊列或持久訂閱消費的消息,回滾機制能確保該消息不被確認,并將它傳送給這些持久實體的下一個消費者。JMS 規(guī)范聲明,發(fā)送給非持久訂閱者的消息會被丟失。該聲明意味著 JMS API 并沒有定義非持久訂閱者消費的消息的可恢復(fù)性。
問. 為什么不能使用 J2EE 1.2.x SDK 運行 JMS API 示例程序?
答:
J2EE 1.2.x 參考實現(xiàn)并沒有包含 JMS API 的實現(xiàn),只包含了它的接口。JMS 參考實現(xiàn)可以作為 J2EE 1.3 的一部分得到,
并可在 J2EE 1.3 服務(wù)器上運行它的示例程序。參見 JMS Tutorial 以獲得關(guān)于在 J2EE 1.3 服務(wù)器上運行簡單 JMS 客
戶端程序的更多信息。
請點擊 Java Message Service API Licensees 查看提供 JMS API 實現(xiàn)的供應(yīng)商列表。許多供應(yīng)商對各自的 JMS API 實現(xiàn)都有示例,能用來運行從網(wǎng)站上下載的 JMS API 例子程序。
問. 根據(jù)規(guī)范,“試圖獲得某個未設(shè)定的名稱的屬性值將被處理為,就好像該屬性已存在,值為 null。”那么對于 getStringProperty,這意味著返回一個 null 值,還是一個 null 字符串?
答: 兩者都是允許的。這是因為一些 MOM 系統(tǒng)壓根就沒有 null 字符串的概念,因此它們將所有值為 null 的字符串在發(fā)送時都轉(zhuǎn)換為空字符串。
問.
用 Connection.setExceptionListener(ExceptionListener) 方法去嘗試處理連接問題,但是當停止服
務(wù)器的時候, 好像沒有 JMSException 被觸發(fā);而且onException 方法也沒被調(diào)用。這是一個 bug 嗎?
答: JMS 規(guī)范并沒有指定傳送給 ExceptionListener 的究竟是何異常,以及它們是何時被傳送的,因此提供者們在如何處理連接問題上是多種多樣的。這方面如果有問題的話,請與您的 JMS 提供者協(xié)商。
問.
依照 JMS 規(guī)范的第 3.4 節(jié),一個客戶端只能有效地設(shè)置消息表頭字段中的三個。所有的其余字段要么由 JMS 提供者設(shè)置,要么由 send
或 publish 方法設(shè)置。為什么所有字段都有一個 setter 方法,當消息被發(fā)送或者被 JMS 提供者傳遞時,任何客戶端的設(shè)置又是在何時覆
蓋原值的呢?難道對大多數(shù)字段只允許 getter 方法沒有意義了?
答: 規(guī)范需要 setter 方法主要是為了保持一致性,因此每個消息
字段都有一個getter 和 setter方法。另一個原因是, 在一個消息被接收后但是在它被傳送到應(yīng)用程序的其他部分去處理之前,允許接收的客戶端
更改消息的某個字段。雖然大多數(shù)的 setter 方法很少被用到,但是它們給了程序員很大的靈活性。
問. 兩個不同的 JMS 服務(wù)能彼此通話嗎?舉例來說, 如果 A 和 B 是兩個不同的 JMS 提供者, 那么提供者 A 能把消息直接發(fā)送給提供者 B 嗎?如果不能, 那么提供者 A 的訂閱者能擔(dān)任提供者 B 的發(fā)布者嗎?
答:
第一個問題的答案是不能,而第二個問題的答案是能。JMS 規(guī)范并不要求一個 JMS 提供者能夠直接發(fā)送消息給另一個提供者。然而,規(guī)范確實要求一個
JMS 客戶端必須能夠接收另一個不同的 JMS 提供者發(fā)送的消息,因此,提供者 A 的一個訂閱者收到的消息能被再次發(fā)布給提供者 B。需注意的
是,提供者 B 的發(fā)布者并不需要處理一個叫 JMSReplyTo 的表頭,該表頭引用一個特定于提供者 A 的目的地。
本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u/10369/showart_200161.html |
|