深入探討SOAP、RPC和RMI
在 Brett McLaughlin 關於Soapbox的第二回閤中,他詳細地將“簡單物件訪問協議”與 RMI 和 RPC 進行了比較,並就開發人員如何在這三種訊息協議中做出最佳選擇而提出建議。他查看了來自 IBM 和微軟的現實世界 SOAP 實現,並檢查了 XML 的侷限性 - SOAP 的基本編碼格式 - 和作為全功能程式語言所涉及的問題。本文包含 RPC 和 SOAP 機票請求的樣本程式碼,用於並排比較。
自從上一次談論臨時講臺以來,圍繞 SOAP 的大量宣傳仍在繼續升溫,毫不奇怪。微軟在其 .NET 平臺中稱讚該協議,Apache 聲稱它是訊息傳遞(至少在我碰到的 XML 圈子中)最要緊的事, 並且每個人都希望獲得它。在 Enhydra 和 jBoss(兩種流行的開放原始碼應用伺服器)以及許多商業應用伺服器公司,正在開發用於 SOAP 的服務。那麼,自從上一篇文章以來,SOAP 故事有哪些變化呢?老實說,幾乎沒有。SOAP 就如同一塊已經獲得了動量準備滾下山去的巨石。問題是您是否正在跟隨著它跑,或站在它下面仰面看著它,希望它不會超過您。我將去除所有市場廣告,並給您一些工具來明確評估 SOAP 是否適合於您。換句話說,我將幫助您,確保不會被那塊巨石壓碎!
本文接著我上一篇臨時講臺,那篇文章深入探討了 SOAP,特別是它在 RPC 和 XML-RPC 方面的基礎。 這裡,我將 SOAP 與 Java 空間中通訊方面,它最大的競爭對手 RMI(遠端方法呼叫)進行比較。RMI 用在 Java 中跨越網路的元件間的通訊上,已有很長時間了,隨著在如 Enterprise JavaBeans (EJB) 技術中使用該技術,它繼續流行。我將研究 RMI 與 SOAP 如何不同 - 包括 SOAP 的現實和 SOAP 的未來展望。最後,我將看一下我稱做的“工作級 SOAP”,這指您現在可以從 微軟和 IBM 下載。本文這部分將從概念性轉向開發人員正在詢問的實際問題的具體考慮:“現在,SOAP 馬上能為我做什麼?”
RMI 還是 RPC?
在這一兩部分系列的第一篇文章中,我研究了 SOAP,確切描述了它是什麼,以及同樣重要的,它不是什麼。特別是,我查看了 RPC、XML-RPC 和 SOAP,剖析了每項技術所包含的。您也許奇怪地發現許多 SOAP 的“特性”,實際上是 XML-RPC 的特性,不是 SOAP 固有的。 也許您還了解到可以用更簡單的包而不是 SOAP 來滿足商業需求,如在 Userland XML-RPC 站點(請參閱參考資料)上找到的 XML-RPC 庫之一。或者,您可能決定,利用 SOAP 的封裝機制,可以方便地編碼應用程式特定的資料型別,SOAP 確實是您所需的。在任何情況下,有了我在第一篇臨時講臺文章中提供的資訊,您應該擁有了足夠的 SOAP 和 RPC 知識,可以與今天程式設計中它的主要對手 RMI 做比較。有許多好的理由要使用 RMI 而不用 RPC,但同樣也有好的理由使用 RPC 而不用 RMI。(難道總是這種情況?)在以下的章節中,討論了在這三種選項:SOAP、RPC 或 RMI 之間作出選擇所必需的主要因素。
它取決於語言
使用 SOAP、RPC 還是 RMI 的決定將根據您使用的程式語言。如果您是 Java 程式設計師, 正好有 作為 Java API 一部分的 RMI -並且它易於上手而且有編制良好的文件。 如果不是 Java 程式設計師,則 RMI 不是自動的選項。事實上, 非 Java 程式設計師會發現 SOAP 是極吸引人的解決方案,甚至對 Java 開發人員也是如此。SOAP 提供了比 CORBA 和其它遠端協議更容易的訊息傳遞和通訊方式。 而且,它為 XML 提供的編碼也是非常便利的:雖然有一些 C 和 Perl XML 語法分析器可用,通常 這要比 Java 在同樣條件下更慢一些(在開發方面)。 所以,SOAP 不但將訊息傳遞新增到您的工具箱,而且還去除了必須用工具來對 XML 進行語法分析的負擔,並且該工具沒有如其 Java 搭檔一樣成熟。
實際上,使用 SOAP 的大多數是 Java 程式設計師,所以又回到了原來的問題,使用 RPC 還是使用 RMI。 如果您是 Java 開發人員,並且必須要與非 Java 應用程式或元件進行通訊,將會怎麼樣?您的應用程式空間的其它參與者可能不能傳送或接收 RMI 通訊。可能安全地說法是他們不希望處理 IIOP 或 CORBA 之間的爭論。但是他們確實能收到 SOAP 交付的友好的、簡單的有效負載。譯碼有效負載和以某種方式(使用 SOAP API 他們自己的語言)響應使通訊能簡單地跨越“程式語言障礙” - 並且這使 SOAP 具有吸引力。
對於作為開發人員的您,這意味著什麼呢?如果您用 Java 編碼,與 Java 交談,除了 Java,從來不需要其它任何事,那麼 SOAP 喪失了一些吸引力; 這時,開發人員接受 RMI 要多於 SOAP,並且更易於學習和使用。然而,對於真正的親 Java 者,SOAP 仍然有一些有利條件(我將在後面談到),它只是沒有那麼吸引人了。如果不在 Java 環境下工作,或者需要與非 Java 環境通訊,那麼 SOAP 開始發光。它使用 XML,這是與廠商和語言無關的, 並且易於使用 Perl、C、Ada 甚至是 COBOL(雖然為何使用 COBOL 是另一場演說的主題)進行語法分析。SOAP 是對如 CORBA 和 RMI-IIOP 這樣的重型範例吸引人的替代。並且,由於現在 SOAP 是一項深受歡迎的技術,其它那些語言的 SOAP API 很快會到來。在這些情況下,可以認為 SOAP 是訊息傳遞真正的朋友。當然,SOAP 不僅僅是訊息傳遞還有更多,現在,我將演示客戶機如何與 SOAP 互動,以及如何與 RMI 互動。
呼叫 vs 請求和響應
在決定是否用 RMI 而不用 RPC 或者反之亦然時,看一下這兩者採用的互動方式是重要的。 互動的 RMI 模型與 RPC 中使用的是完全不同的:在如何操作遠端物件方面有顯著的不同。事實上,在 RPC 和 SOAP 中,根本不直接操作遠端物件!為了闡明這一點,我將深入探討該模型。
在 RMI 中,遠端物件按照好象它是本地行事。客戶機應用程式直接呼叫遠端物件存根上的方法。通過 RMI 和 Java 的魔力,該存根使可以跨越網路編碼方法呼叫,並且最終結果是,使另一臺機器上的物件呼叫了一個方法。然後,結果類似地編碼,並返回給存根,該存根將結果返回。對客戶機來說,它似乎沒有涉及遠端物件。也許用這種互動方式的最大好處是型別安全以及直接使用方法名是可能的。換句話說,遵循了正常 Java 約定:呼叫了一個方法,如果引數不正確,則發生編譯時錯誤。然而,我必須告訴您,該方法有不利方面。許多異常最終是包裝在 java.rmi.RemoteException 中。所以,您必須確保在呼叫 RMI 物件的應用程式中有一些知識,否則您會丟失在 RemoteException (可能 NumberFormatException)中的包裝資訊。結果是缺乏關於出錯的資訊。
替代物 RPC 風格的呼叫遵循完全不同的道路。與其涉及正在呼叫的方法,倒不如有要傳送的訊息,基本上是對遠端伺服器的請求。然後,明確表達響應,並返回響應。在這種情況,客戶機從來不直接呼叫方法。請求通常由呼叫遠端伺服器上的方法名稱和引數組成。然而,這些全部是編碼的。清單 1 顯示了程式碼片段,請求預定和購買機票。
現在,我知道您可能有一種被欺騙的感覺,因為本文是關於 SOAP 的文章,而您正在獲取 XML-RPC 程式碼樣本。為了完整性緣故,請檢視清單 2 中使用 SOAP 的相同呼叫。
到現在,與 RMI 相比,使用 XML-RPC 還是使用 SOAP 都無關緊要;XML-RPC 與 SOAP 中客戶機與伺服器之間的互動是一樣的,而且這兩者與 RMI 有巨大的區別。在這些清單中所看見的方法名和引數是以 String 或 Parameter 編碼的(取決於所使用的技術)。您還看到查詢必須按名稱進行 - 而不是通過獲取 Java 虛擬機器中實際 java.lang.reflect.Method 的控制代碼,如 RMI 中一樣。使用這種 RPC 編碼風格可能有更多事物出錯:伺服器上的方法可能丟失,或者客戶機上的方法可能拼錯。其它可能遇到的問題是自變數型別不正確,指定的自變數名稱不正確;或者伺服器當機。用 RPC,所有這些問題都是執行時問題,而用 RMI (除了伺服器當機)這些問題可能是編譯時問題。通常,最好在編譯時間捕獲問題而不是在執行時。問題是使用 RPC 或 SOAP 使您失去了 Java 編譯器的大量便利。
RPC 風格確實提供了一些有利之處。首先,它允許客戶機與伺服器之間有更大的獨立性。不象 RMI,無需生成存根類並將它們傳遞給客戶機。伺服器無需讓客戶機知道,就可以完全關機和被替換。(在 RMI 中,可以做到這一點,但實現起來要困難得多。)事實上,沒有中斷客戶機處理,可以在呼叫間升級和重新編譯伺服器上的類和方法。並且使用 SOAP(與 XML-RPC 單獨對比),可以用 SOAP 的故障機制,API 的標準部分,來轉播客戶機可能發生問題的大量資訊。
再一次。我讓您根據工作中 RMI、RPC 和 SOAP 的使用來做出判斷。在某些情況下,SOAP 有明顯的優越性:它非常適合非同步通訊和針對鬆耦合的客戶機和伺服器。但這種好處會招致一些不利結果。必須做大量的執行時檢查,而且開發人員喪失了許多可以確保方法和引數是正確的編譯時便利。如果您已經讀過我的關於臨時講臺的第一篇文章,那麼我確信您知道我想說的:評估您的商業需求。去蕪存箐。您很可能會發現,在某些情況下,發出 SOAP 呼叫,然後讓遠端伺服器平靜地處理任務非常管用;在其它情況下,希望使用 RMI 來進行 Java 到 Java 的通訊以及為確保編譯時的型別安全。
工作級 SOAP
我已經將 SOAP 與 RPC、XML-RPC 和 RMI 作了比較,研究了它們之間的不同以及優點和缺點。現在還不是結束的時候;我還需要考慮一些關於 SOAP 自身的問題。到目前為止,關於 SOAP 的討論是集中在 技術的“概念性實現”;我已經演示瞭如果按 "as is" 來實現規範,那麼 API 行為如何。在現實中,沒有所謂的完美實現。記住,工具箱是由人開發的!記住,在下一節中,我查看了實際的 SOAP 實現 - “工作級 SOAP”是什麼樣子,以檢視如何,以及如果,交付 SOAP 的許諾。
實踐 vs 展望:IBM 和 Microsoft 的 SOAP
實現和規範如何相互符合呢?兩個主要的 SOAP 實現在開發中,一個來自 Apache, 作為 IBM Apache XML 專案的一部分,一個來自微軟,作為它的 .NET 平臺的一部分。在這兩種情況下,在公開發行方面都不到一年的時間,帶來了實現的成熟性問題。
也許來自 Apache XML 最期望的發行版,Apache SOAP 工作,是 IBM 原來在 SOAP4J 上工作的延伸。給予 Apache 的 SOAP 版本號是 "2.0",很難與許多其它 2.0 的產品相提並論,那些產品通常是很健壯。規範包含大量還未新增到 SOAP 2.0 的項;然而,在大多數應用中不需要這些中的大部分。其不利之處是為了符合規範必須支援這些少數的、不經常使用的項。直到實現它們,您才會使用它們,SOAP 工具箱也許沒有進行效能調整,因為工作仍然在特性上進行。遺憾的是,您為那些不常用的特性付出了代價。
微軟的 SOAP 實現,.NET 平臺的核心部分,在 SOAP 的功能和符合方面,幾乎提交到 W3C 的 SOAP 一致。這將極有可能繼續成為真的,由於 SOAP 是大多數通訊將在 .NET 平臺中出現的方法。 元件之間通過 SOAP 互相通訊的能力 -在開發和生產中 - 是 .NET 的主要特徵之一,所以不要展望微軟的 SOAP 實現會動搖。同時,您也應該展望許多專有特性做到微軟實現中。有了這些“鉤子”,微軟碟機動的產品將能夠利用特定於 .NET 平臺的捷徑。如果您正在使用微軟的全部產品,這些鉤子會很有用處;然而,如果您正在嘗試用普通的 SOAP 實現,要注意了!
底線是 SOAP 還處於在快速發展階段,並且今天的 SOAP 並不完全是未來許諾的 SOAP:來自 IBM 和微軟的 SOAP 實現仍然正在開發和完成。不要期望現在開始使用 SOAP(通過這些專案之一)並在幾個月內能夠無縫地升級至新版本;特性會改變,功能性會改變,隨之會產生一些混亂,通常會導致對應用的其餘部分的修改。 另外,如果 W3C 將 SOAP 作為一種新規範接受,在最終建議書交付之前,會有幾個修訂版。這些修訂版會導致 SOAP 實現的額外變更,這當然意味著對您的開發環境進行更多升級。
總之,對於目前的 SOAP 實現,它還有很多路要走。如果您沒有陷入到實現細節中,並且當升級版出現時願意有靈活性,那麼可以從使用 IBM 和微軟的現在 SOAP 實現中學到許多。可以調查 RPC 是如何工作的,遠端方法如何定位,以及 SOAP 信封和故障機制行為。換句話說,當 SOAP 的完整和穩定的實現確實到來時,您可以很好地走在這項競賽的前面。
關於 XML 的說明:您全部所需?
關於 SOAP 供應商,最終的警告是:不要在 XML 上下賭注。我確信我錯誤地引用了這句話,所以聽我把話說完。XML 還在這裡。但 XML 最適合於較大的應用程式環境,用真正的程式語言,如 Java 來支援它。 有一些人說,“XML 足夠了。”隨著實際應用領域中增添了如 SOAP、XML-RPC、 RSS (RDF Site Summary) 和其它 XML 詞彙,人們正提倡將 XML 本身作為一種程式語言。使用 Apache Cocoon、XSL、XSLT、SOAP 和一種 XML 資料庫, 使人們相信不用編寫一行 Java 程式碼,仍然能夠執行整個應用程式。(公平而言,在 Cocoon 中實際沒有人建議這麼做;它只是一個示例。)
這前提僅僅 XML 需要,而該前提本質上是有缺陷的。 使用 XML 要有代價:與二進位制格式相比,編碼要花費更長時間,而且經過網路傳送時,它更大些。XML 的好處是它可以跨程式語言和跨平臺理解。但是如果您不需要這種全面的功能,那麼 XML 就沒有多大意義了!例如,在同一個應用程式中的 servlet 和 EJB 之間使用 XML 就是一個壞想法。這需要花時間來處理 XML 和花資源來傳輸 XML,並且什麼也得不到。
SOAP 是工具。它應該只作為工具使用,幫助應用程式進行訊息傳遞和資料表示。這些應用程式需要的不只是 XML。我可以理解某些人提倡不要被 Java 所束縛 - 尤其當 Sun 已經顯示不願意為該語言建立開放標準過程 -嘗試簡單地用 XML 作為 Java 的替代物是不切實際的。所以,把 SOAP 和 XML 作為工具箱中的更多工具。雖然它是多功能的、功能極其強大的工具,但它仍然只是一件工具。
結束語
在這一兩部分的文章中,我研究了備受矚目的 SOAP。我對它進行了剖析,把它作為與其先輩 RPC 和 XML-RPC 進行了對比,並且將它與其主要竟爭對手 RMI 進行了比較。我還查看了可用的 SOAP 實現對比 W3C 的實際 SOAP 說明)。即使您還未對 SOAP 做出決定,在這一點上,您應該能夠認識到其優點和其問題。
我希望您開始形成您自己的關於 SOAP 狀態的觀點。如果等待某種命令來告訴您 SOAP 是否是 “好的”還是“壞的”,那麼這是不會發生的。坦白的說,我不能告訴您是否您應該使用 SOAP。但我可以告訴您,今天在許多情況下,開發人員正在使用 SOAP,而改用 XML-RPC 的話,可能是足夠和易於程式設計的。除此以外,XML-RPC 庫要比 SOAP 庫成熟得多。與此同時,某些程式設計師每天掙扎於 Perl 和 C 元件、C 和 Java 元件之間的通訊。這些開發人員可以從轉向基於 SOAP 或基於 XML-RPC 的通訊模型中獲益匪淺。另一方面,從不轉向 Java 以外語言的 Java 開發人員可以轉向 RMI 而不是使用 SOAP,他們會看到極大的效能改善。
我將留給您我重複多次的基本建議:“去蕪存箐”。在您對 SOAP 感到太興奮之前,要確保它符合您的商業需求。如果它不符合,不要害怕技術性“當前”比同仁要少;對有簡單的、成功的應用程式的滿意遠遠超過為了在應用程式中使用最時髦的技術而使用如 SOAP 這樣的技術引起的麻煩。無論怎樣,關注 developerWorks XML 專區,因為我會緊密監控和涵蓋與 SOAP 相關的任何新開發。而其他開發人員會輪流站上臨時講臺。
參考資料
通過單擊本文頂部或底部的討論,可以參加本文的論壇。
通過閱讀 W3C 的說明:SOAP 1.1 Note 來專心致志於 SOAP。
在 xml.apache.org 上獲取從 XML Apache 的實現。
在 MS SOAP SDK vs IBM SOAP4J 和 MS SOAP SDK vs. IBM/Apache XML-SOAP 這兩篇文章中,將 IBM 的 SOAP 實現與微軟的 SOAP 實現做了比較。
在 Userland XML-RPC 網站了解關於 XML-RPC 的內幕,其中您可以發現幾個 XML-RPC 庫。
請閱讀 Brett 所著的 Java and XML 一書中更多有關 XML 和相關技術。
關於 IBM 的 SOAP 安全性擴充套件頁面描述了把安全性保衛措施新增到 SOAP 實現中的建議(包括至 Note to the W3C 的連結), 以及一個帶擴充套件的 SOAP Envelope API。
IBM 的 Web 服務實情表簡要說明了 SOAP 如何符合 Web 服務倡議,並提供了其它資源連結。
在倫敦舉行的 IBM Solution 2001 開發人員大會上,2001 年 5 月 17 日星期四的會議上提到了 SOAP、Web 服務和 MQSeries 系列。