《實踐與思考》系列連載(5)——問答Hprose,以及關於技術與開源的思考...


作者: 陳希章 發表於 2010-07-18 18:29 原文鏈接 閱讀: 481 評論: 6

引子

之前我寫過一篇文章,討論了在XML Web Service或者WCF中,多次發起異步調用可能導致的問題,請參考http://www.cnblogs.com/chenxizhang/archive/2010/05/31/1747812.html

在這一片文章中,我介紹了問題的症狀以及發生的原因,及其解決方法。這篇文章收到了一些反饋,其中有朋友介紹到了Hprose這個產品。我後來也實際用了一下,確實在Hprose中是可以避免這種問題的。(有興趣的朋友,可以參考這裏 http://www.cnblogs.com/chenxizhang/archive/2010/05/31/1747812.html#1873774

本着實踐和求真的精神,我也專門對Hprose這個產品也做了一些深入的探究,包括和他們的開發團隊做了一些交流。同時,因爲這個產品是商業開源(與一般的開源還不太一樣),所以也引發了一些對技術和開源的思考。今天整理出來,給大家參考參考

 

什麼是Hprose?

Hprose (High Performance Remote Object Service Engine) 是一個商業開源的新型輕量級跨語言跨平臺的面向對象的高性能遠程動態通訊中間件。它支持衆多語言,例如 C++, .NET, Java, Delphi, Objective-C, ActionScript, JavaScript, ASP, PHP, Python, Ruby, Perl 等語言,通過 Hprose 可以在這些語言之間實現方便且高效的互通。

Hprose 是商業開源軟件,在取得 Hprose 商業使用授權後,您可以將它用於您所擁有所有權的商業項目的開發當中,Hprose 商業使用授權沒有開發者人數、服務器CPU數量、授權年限等限制,但對二次分發有一定的特別要求。如果您所開發的項目或產品涉及到對 Hprose 的二次分發,還需要取得相應的二次分發授權。

關於Hprose的詳細介紹和有關資源,請訪問其官方網站: http://www.hprose.com

 

問答Hprose

下面記錄了我和他們的團隊幾次郵件交流討論到的幾個一些問題。取自郵件的原文,比較直白,但是原汁原味。

問:協議層面,我關心的是主要包括兩個層面:Hprose如何支持不同的傳輸協議(例如Http和Tcp或者還有更多的),以及Hprose的數據序列化格式是否有公開的規範書?

答:協議實現方面我們是這樣考慮的,通過uri來區分不同的協議,目前http://、https://開頭的是表示Http客戶端和Https客戶端,他們由HproseClient的子類HproseHttpClient來具體實現。當以後提供tcp、udp等實現後,tcp://、udp://開頭的表示TCP客戶端和UDP客戶端,他們可能會分別由HproseClient的子類HproseTcpClient和HproseUdpClient來分別實現,每個不同類型的客戶端肯定會有他們特有的屬性,並且內部通訊機制也完全不同,所以由不同的子類實現是必要的,但是它們又都是HproseClient的子類,在不需要設置特殊屬性的情況下,可以使用HproseClient來統一訪問,另外,當tcp、udp版本實現之後,我們會給HproseClient類提供一個工廠方法,通過不同協議的uri來創建不同類型的HproseClient對象不需要指定使用哪個子類,這樣就可以將不同協議的實現進行統一管理了。

【我的評論】這個做法也是可以的,採用類似於.NET中WebRequest那種工廠方法模式的設計,也能保證一定的靈活性。雖然與WCF那樣通過配置文件直接就可以改變傳輸協議(其實是所謂的binding)的做法是有些差別的。


而數據序列化協議部分,目前我們沒有公開的數據格式描述文檔,這部分我們以後可能會通過標準或者專利的形式進行發佈。格式的公開不是一個簡單的問題,它有多方面的因素所制約,AMF這個格式從最初制定實施到最後公開也是花了5-6年的時間(2002-2006年制定,2007年公開發布),對於Adobe那樣的大廠商尚且如此,對於我們而言也需要慎之又慎啊。

【我的評論】可以理解

 

問:數據傳輸層面,有沒有辦法由用戶決定是否進行加密或者壓縮?

答:可以由用戶來決定加密和壓縮。目前壓縮是通過直接使用http的壓縮方式,服務器端有個IsCompressionEnabled開關,當打開這個開關後,客戶端只需要添加Accept-Encoding: gzip,deflate這個http頭,就可以開始壓縮傳輸了。不過說實話,壓縮開啓之後,數據量不夠大時,數據壓縮之後反而會增大,而且數據壓縮傳輸會對CPU消耗相當嚴重,所以我們是不推薦使用壓縮傳輸的,因此文檔中並沒有提到IsCompressionEnabled開關,也沒有說明客戶端如何開啓壓縮傳輸的方法,這樣可以避免用戶在誤用這個功能後抱怨佔用太多CPU。至於用戶自定義加密傳輸,我們現在還沒有提供這個功能,一是因爲https本身可以提供加密傳輸,在tcp上也可以通過tcp+ssl實現加密傳輸。因爲ssl是標準的,所以要比用戶自定義的方式可靠一些。另一個原因是,加密傳輸要保證安全性需要用到密鑰交換技術,這個同樣佔用大量的CPU計算時間,我們在Hprose的前身PHPRPC中提供了這個功能,但是我們發現它帶來的這個缺點遠遠大於它所帶來的問題(例如黑客可以通過這一點很輕鬆的發起DoS攻擊,導致服務器計算資源耗盡而停止正常服務)。另外,密鑰交換本身必須是一個同步調用的過程,在實現遠程異步調用時,又要保證同步,會大大增加實現的複雜度,以及降低異步調用的效率。所以對於自定義加密方式傳輸的功能,我們目前的1.x版本中還不打算加入。當上面所說的幾個問題能夠找到有效的解決方法之後,我們會在Hprose 2.0或者Hprose 3.0中,以插件的方式來提供。

【我的評語】我們樂見這個設計的完善

 

問:是否有考慮過REST方面的支持?

答:REST相對於RPC是另外一種構架模式,Hprose提供了一種序列化機制,同時在這種序列化機制上構建了一個RPC機制。所以如果在Hprose的序列化機制上使用REST方式來構建系統也是完全可以的,但是這時候就完全不需要Hprose提供的客戶端和服務器了,只需要Hprose的IO(序列化反序列化)部分就可以了。但是REST構架最大的問題是,它沒有一個統一的標準,不能向RPC那樣可以保證接口的互通性。而且應用的範圍我認爲也不應存在太大的交集,現在很多采用REST方式來提供類似Web服務功能的用法,大多都是對REST的誤用,並沒有發揮出REST本該發揮的優勢。現在的REST已經像當年的XML一樣被當成了萬能靈藥,而實際上,這已經背離了REST的本意。而Hprose既然是爲RPC在XML火爆的年代中所犯下的錯誤做出的糾正,就不應該在REST火爆的年代犯下同樣的錯誤。所以即使Hprose的序列化機制確實可以用於真正的REST應用,我們也不會明確的告訴大家Hprose可以做REST服務,因爲在大多數人並不能真正認識REST的年代,這樣說就是對用戶的誤導。

【我的評語】基本同意。對於REST,還是可以多從實踐的角度去辯證地看待。

 

問:OnError事件的做法存疑,如果一個client發起了多次請求(方法名也是一樣的),那麼怎麼區分呢

答:OnError事件確實存在您說的問題,這個問題我們在JavaScript、ActionScript、ASP這些版本中已經提供了在調用中直接提供跟調用綁定的錯誤處理回調的方式來解決了。但是C#、Java等這些版本我們在1.2版本中尚未提供這種解決方案(未提供的主要原因是用戶對這個功能沒有強烈需求)。但這個解決方案我們會在1.3版本中在所有語言中統一的。

【我的評論】這個機制還是需要完善起來,現在有用戶對這個功能有強烈要求了不好意思

 

問:身份驗證方面,我看到目前文檔的說明是可以直接改寫Http的頭,添加Authencation這個標頭。

  • 我要說的是,這個部分最好有改進。目前這種做法易用性不高,會讓人生畏。ADO.NET Data Service早先就遇到這個問題,後來改進了
  • 身份驗證和授權歷來都是很重要的。身份驗證本來就有標準的做法,例如給Client類型添加一個Credentials這個屬性。而授權應該可以結合自定義Attribute或者給予Url的做法可能是較爲合適的
  • 後續這個方面最好有一些例子

答:對於.NET版本,我們確實提供瞭如您所說的Credentials屬性,這個屬性我們沒有在手冊中列出(因爲他在其它語言中不存在,另外,.NET的某些版本中也不支持這個屬性,例如SilverLight,這跟.NET本身有關),但是在使用時您會發現他確實存在。在服務器端授權方面,我們提供了 OnBeforeInvoke 事件,在該事件中可以對認證授權進行統一處理。我們不使用 Attribute 的原因是,我們認爲 Attribute 不是一種鬆散耦合的解決方案,它對所發佈的服務具有侵入性,我們設計的目標是,任何可以直接用於本地的方法都可以直接發佈爲遠程方法,而不需要對它做任何修改或修飾。這樣纔可以保證,對於我們不具有源碼的類也可以無需包裝就作爲遠程服務發佈,並且還可以對授權做集中控制。

【我的評語】這個設計我認爲還是要改進,讓用戶使用起來更加方便一些

 

問:開發工具和服務描述方面的支持

  • 這個部分最好有改進。例如我看到,如果直接在瀏覽器中輸入服務的地址,會看到幾個字符。那不是一個友好的設計。你可能主要是從開發者角度看這個問題了,而不是用戶角度。
  • 其實這一點可以借鑑WCF或者Web Service的wsdl做法,人家好的東西也可以吸收的

答:WSDL存在的意義在於它是上一代靜態遠程調用機制所必需的中間語言,就如同CORBA的IDL、ICE的Slice一樣。與IDL和Slice不同的是,在.NET中,WSDL是根據服務自動生成的(但是對於PHP、Python這些非.NET上運行的語言,它們無法自動生成WSDL,需要手工編寫,所以在PHP、Python等動態語言中發佈WebService是相當痛苦的一件事情)。而Hprose是新一代的動態遠程調用,所以不需要WSDL這樣的中間語言。通過瀏覽器來查看Hprose的服務地址顯示的遠程方法列表雖然對用戶來說不夠友好,但是相比WSDL來說,Hprose的輸出還是簡單易懂的多。所以,我想您所說的WCF和WebService提供的用戶友好的界面應該是指的在線調試界面,而不是WSDL那個頁面吧。針對這個用戶調試界面,我們提供了忘憂草(在線試用版地址:http://www.hprose.com/nepenthes/)這樣的專業調試工具,用戶如果需要調試服務,可以直接在這個調試工具中輸入服務器地址,這樣不管用戶的服務是使用何種語言在何種平臺上發佈的,都可以採用同樣的方式進行調試。而且隨着這個調試工具的升級,用戶以後可以用更加友好的界面來調試之前的服務,而不需要連同服務一起更新後才能使用新的調試界面。這都是我們爲什麼要採用這種分離式調試工具的原因。而您所說的WCF和WebService服務發佈後的調試界面是.NET中特有的,如果用其它語言發佈WebService服務,並不會得到這樣的調試界面,所以,不同語言下的WebService服務,用戶體驗會有相當大的差別,而且用.NET老版本發佈的WebService服務也不可能使用新版本.NET發佈WCF服務的調試界面來調試,當然這並不是微軟的錯,而恰恰這是微軟的策略,因爲只有這樣才能將用戶牢牢的綁定於.NET平臺之上,並且讓用戶始終追求使用最新版本的.NET平臺開發工具,只有這樣才能保證微軟持續盈利。而我們的出發點恰恰相反,我們是要爲所有平臺所有語言的用戶提供統一的用戶體驗,所以我們採用了截然不同的設計方式。

【我的評語】提供類似於WSDL這樣的服務描述(甚至有配套生成客戶端那個接口的工具)肯定是對的做法,讓用戶使用起來更加方便纔是目標。統一的用戶體驗固然是沒錯的,但統一的用戶體驗不是說統一的不高的用戶體驗。

 

問:如果服務器端有兩個類,他們擁有同名方法,則它們是無法區分的。看起來是以最後註冊的類爲準。這個有沒有什麼可能的問題。也就是說,在Client端Invoke的時候,只是提供了functionName,而沒有辦法提供服務類的名稱。

答:你說的這個問題,我們一開始就已經考慮到了。所以我們提供了一個別名機制,如果以類(或對象)爲單位發佈服務,則可以爲每個類(或對象)指定一個服務名成空間(該名稱空間在發佈服務時會變爲方法前綴),而對於以方法爲單位發佈服務時,則可以爲每一個方法指定一個完整的別名,通過完整的別名,就可以區分在定義時名稱相同的兩個不同方法了。這部分在文檔的後面部分(客戶端部分)有比較詳細的說明。
例如您的這個例子可以這樣改寫:

    class Program

    {

        static void Main(string[] args)

        {

            HproseHttpListenerServer svr = new HproseHttpListenerServer("http://localhost:2010/Hprose/");

            svr.Methods.AddInstanceMethods(new MyService(), "s1");

            svr.Methods.AddInstanceMethods(new MyService2(), "s2");

            svr.Start();

            Console.WriteLine("服務器已經準備就緒");

            Console.Read();

        }

    }

【我的評語】這是不錯的

 

問:對於開源的理解

答:我對開源的認識,大概開始於10年之前第一次接觸Linux吧。那時的Linux發展了已有10年之久,因爲其開源,功能又不遜於Unix,因此許多公司都希望藉由Linux操作系統,來取代昂貴的Unix,以便在激烈的競爭中取得有利的地位,這方面的代表是RedHat、SuSE等商業化 Linux 版本。而另外一些個人或組織則爲了教育科研的需要而開發了適合自己的Linux版本,這方面的代表是Slackware。還有一部分個人和組織則是爲了興趣和自由的理想而開發他們自己的Linux版本,這方面的代表是Debian、Gentoo等。雖然大家做的都是Linux,但是出發點不同,因此各個產品之間當然會出現很多的差異化,以致於想要開發一個可以在所有版本Linux都能運行的程序都是一件很困難的事情。Linux陣營因此而分裂,形成了諸侯割據的局面。各諸侯之間的爭鬥一直在繼續,一批死去,一批新的又起來,何時才能統一,不得而知。
而Windows自始至今都是不開源的,也正是因爲這樣,Windows才保持了統一的局面,而沒有像Linux那樣四分五裂。儘管Linux陣營常常以Windows不開源爲藉口來打擊Windows,但是Windows的霸主地位始終沒有絲毫的動搖,相反因爲Linux陣營的四分五裂,各個廠商之間各懷鬼胎,雖然勢衆,但並不能團結一致,甚至一些公司爲了自己的私利,還跟微軟簽署了合作協議,例如Novell(SuSE和Mono的開發公司)。這就像蘇洵在六國論中指出的“六國破滅,非兵不利,戰不善,弊在賂秦”一樣,Linux照這樣發展下去最終必會敗於Windows系統。
Linux的開源始於對自由理想的追求,但好的理想卻常常會被惡的思想所利用,以致善始而不能善終。

 

我理解的開源是這樣的:
OpenSource != Free != No Charge
開源的目的一般分爲以下幾種:
1、以自由作爲理想的開源。代表爲GPL開源許可。GPL的發起人鐵人(他名字的直譯)是一個理想主義者,他認爲軟件是自由的,一個軟件被開發出來之後,人人都可以修改它,人人都可以維護它,任何人都不可以剝奪別人修改軟件的自由。但是他的這個理想常常被人誤認爲軟件必須是要免費的。也就是被誤認爲 Free == No Charge,但實際上,鐵人並沒有這個意思,而且他自己也確實在通過他的自由軟件所盈利。
2、以打擊競爭對手或者潛在的競爭對手爲目的並把開源貢獻者作爲免費勞動力的開源,代表爲Apache基金會、Mozilla基金會。Apache基金會幕後最大的支持者是IBM,IBM通過贊助Apache基金會來開發一些免費的開源項目,這些開源項目最大的特點是商業友好,也就是說,可以免費的拿來商用且不用繼續開源,Apache的開源項目作爲一個試驗田,由衆多小公司拿來免費使用,在使用過程中遇到問題並不能得到任何的商業支持,只能通過自己努力來解決,解決之後在反饋給Apache組織(當然也有大部分人並不會提交自己的努力成果)。而IBM則會拿Apache的那些半成品來經過自己的優化之後,做成高端產品,再以高價賣給高端客戶。這樣,低端客戶有免費的Apache開源項目使用,雖然難用但因爲不用花錢,所以就不會選擇收費的其它低端市場定位的同類商業產品,儘管那些商業產品可能要比Apache的開源項目優秀的多。而高端用戶有因爲不在乎花錢,所以只買最貴的,因此IBM的產品就成了他們的首選。IBM通過這種方式有效的打擊了低端市場的同類產品,使他們無法成長爲可以跟IBM叫板的競爭對手。而Mozilla基金會可以說是一個復仇組織,當它的前身Netscape被微軟的IE消滅之後,Mozilla就把打敗微軟的IE作爲了首要目標,因此Mozilla的開源免費完全是爲了解決掉微軟的IE。不過螳螂捕蟬,黃雀在後,Mozilla經過這麼多年的發展,雖然終於可以爭取到一點IE的市場份額了,沒想到Google的Chrome也進入了瀏覽器競爭市場,面對這兩大高手,Mozilla要翻身恐怕是很難了。
3、爲了讓客戶放心使用而開源。代表是微軟和Hprose。微軟現在有很多產品會對某些要求查看源碼的客戶開源,比如某些國家的政府,這種開源僅僅是爲了讓客戶放心使用,證明自己沒有留下什麼後門。Hprose的開源也是類似的想法,對客戶開源,讓客戶放心使用,當然如果客戶遇到問題,因爲手中有源碼,也可以更容易的反饋錯誤,我們就可以更快的完成錯誤修正。所以,這種開源方式是一種雙贏的做法。
4、盲目開源。代表是Sun。他在IBM的慫恿下,把Java開源了,最後IBM搞出了自己的JVM,賺翻了。而Sun自己一分錢沒賺到,最後把自己公司都搭了進去,以致於最後落了個被Oracle收購的下場。

【我的評語】對於開源向來大家理解都不一,上述總結比較中肯。我個人也贊同:開源不等於免費


 

問:那個PHPRPC開源,你怎麼評價?


PHPRPC 現在是以GPL形式開源的,也就是說,它也是一個理想主義的產物,任何人都可以得到它,修改它,使用它,卻不能獨自擁有它,不能將它私有化。實際上PHPRPC也是我們的一個產品,但是它只能用於同樣採用GPL發佈的項目中,我們對它也提供收費的商業支持,但實際上,你知道的,我們根本不可能在這方面得到一分錢的收入,因爲在國內,只有理想是不能養活一個公司的,甚至連個人都不能養活。呵呵。但是既然已經做了,就讓它繼續下去吧,只要它還活着,就代表我們還有理想,我們還在奮鬥!

【我的評語】爲理想和奮鬥者而鼓掌

 

最後,我還是要表達我對Hprose的整體評價:

  1. 我對Hprose的構想和設計比較讚許,跨平臺跨語言支持當然是很多程序員乃至CTO們孜孜以求的目標。而Hprose在實踐這樣的目標,這最起碼是值得我們學習並且爲之歡欣鼓舞的。希望這個產品能精益求精,做得更好,並且能得到更多人的瞭解和使用。

  2. 對於Hprose團隊的創造性工作和認真態度,我是頗感欣賞的。希望他們能堅持理想,實現理想。對於開源,經常有人感概說,看似很好,但實踐起來卻殊爲不易,我自己也深以爲然。從這方面而言,更應該贏得我們的敬意和支持。

 

 

【備註】以上言論均代表個人意見,如有雷同,純屬巧合鼻血

評論: 6 查看評論 發表評論

百度期待您的加盟


最新新聞:
· 微軟不爲外界所知的十件趣事(2010-07-18 22:58)
· 中國第2季搜索引擎市場規模達26億 百度破70%(2010-07-18 22:54)
· Facebook用戶數下週達5億 邀請用戶共享故事(2010-07-18 22:49)
· 開源的可視化編輯器 KindEditor 3.5.1 發佈(2010-07-18 22:35)
· WordPress 陷入開源‘邊界’之爭(2010-07-18 17:47)

編輯推薦:揭祕Facebook背後的那些軟件

網站導航:博客園首頁  個人主頁  新聞  閃存  小組  博問  社區  知識庫

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章