1/26/2007

[ 翻譯 ] Zed on Ruby, Rails, Mongrel, and More

去年三月 O'Reilly 訪問了 Mongrel 作者 Zed Shaw,想翻譯這篇的原因是因為 Javaeye 上面 alang 發表了簡體翻譯,本來想說直接翻成繁體就好了,不過發現到有些部份原翻譯者並沒有翻譯,順便多翻譯了一下,也幫忙潤飾一下文字成為台灣使用者比較習慣的文法。雖然有不少部份修改,但是本翻譯 50% 以上內容還是改自 alang 的簡體翻譯,並且訪談內容版權屬於 O'Reilly 所有,在此感謝,如有爭議請來信告知。裡面如果有那幾句忘了翻譯,也請指正。


感想:

在 去年三月時,Mongrel 作者 Zed Shaw 提出他想利用 Mongrel 補齊 Rails 在 Enterprise 那一塊的缺口,到現在 Mongrel 發表 1.0 版的同時,Reverse Proxy + Mongrel Cluster 已經是使用 Ruby on Rails 公司的基本配備,看起來 Zed 似乎已經完成當初的夢想了,恭喜 Zed ,Ruby on Rails 也因為有了他,成長才能夠如此迅速。

摘要:

Zed Shaw 在一開始指出有了 Mongrel 的 Ruby on Rails ,已經是一個 Enterprise Ready 的 Framework,並且他已經被許多使用者拿去 Run Real Business。他並且提出一些小故事,間接驗證 Mongrel 的安全性是很良好的。(Apache 擋不住的攻擊,但是被 Mongrel 擊退了)

他在文中也提出許多 Ruby and Rails 社群應該反省的事情
  1. Ruby 執行效能不應該被輕視,雖然我也是輕視的那一群
  2. Win 32 社群不該被輕視
  3. Ruby on Rails 已經有點擁種,該是輕量化的時候了
  4. Active Record 應該增加一些 Connection Pool 設計
並且他也開始著手構思繼續建制一個良好的 Cache Proxy。

本文開始

Zed Shaw 是一個在Ruby世界中漸漸聲名大噪的程式設計師,它是Mongrel的作者,因快速、穩定、安全而出名。在這個訪問中,他討論了Mongrel,Ruby,和他的創建良好程式碼的經驗。

問:你是怎麼進入Ruby世界中的?

答:多年前,我在開發一個怪異的控制工具--我叫它FastCST時--接觸到Ruby時。我試了一下Ruby,但是不得要領,馬上就回到了C語言了。當我讀了Curt Hibbs的文章時,才瞭解到,「Hey,他們在用這個東西在做DSL (domain specific languages )。」從那時起,我就開始開發一個Ruby版本的FastCST,但是很快就被其他的Ruby on Rails 的有趣 Project 所分心。

問: 當某人說他使用 Ruby 時,通常大家就直接連結到他在使用 Ruby on Rails. 你在 Ruby 上面的時間,以及 Ruby on Rails 的時間比是多少?

答:我必須說我在 Ruby 上面主要的工作,也就是 Mongrel ,就是為了支援 Ruby on Rails,以及其他使用 Mongrel 的 Project。但是我每天的工作就是使用 Ruby on Rails。

我喜歡 Ruby 的原因是因為你可以簡潔的表示你想要表示的東西,但是在可讀性上卻相當的清楚。當然有些不好的地方,但是 Ruby 以不可思議的速度加快了我開發的速度。這個語言不可思議的結合了 DSL 跟 OO 語言,並且讓我的開發程式,以開發程式雛型的速度,但是卻有產品的品質。


問:許多人都在說,Ruby和Rails對於「企業級應用」還沒準備好,你怎麼看這個問題?

答:在回答這個問題之前,我必須要明確人們所謂“企業級應用”的定義,可以概括為三點:
1、龐大、昂貴
2、可擴展性,性能,滿足我的服務需求
3、有保障的商業技術支持,用來保護潛在的損失。

問:OK,讓我們一點一點的來談,Ruby和Rails都是免費的,它們怎麼得到花費昂貴的人們的認可?

答:「企業級應用」意味著你要花費上百萬的金錢在硬體和軟體上,但是這個觀點是錯誤的。這麼多年來,他們一直在灌輸這個觀點,是因為他們要從中獲取你購買他們產品的利益。實際上你的解決方案要符合你的真實需求。如果你需要一個龐大的解決方案,是因為你並沒有真正瞭解你到底需要甚麼。Rails 顯示了這樣的「企業級應用」是個錯誤的想法,這些事情其實並不需要,而且 ROI (投資報酬率)也會很差。

Rails 正在做的事情就是證明你不用花一堆錢在「企業級應用」,依舊可以做大事情。Rails 可以做真正的 business。他已經讓一些企業家只花少許的基本投資,就可以實現他們腦中的想法,並且賺大錢。我知道紐約的一些小公司已經用很少的開發者,就可以建構起他們自己的站台。像這樣「減少開始創業的風險」足以證明 Rails 可以應付真正的 business。

問:那麼,Rails的可以擴展性呢?

答:那些企業級應用中的「擴展性」,我都可以用Mongrel來解決。首先,要把「可擴展性」與「高性能」要區別開來,同時要回到「資源的可以擴充性」上來。一旦你把「可擴展性」與「高性能」這二者區分開來,你就能兩者皆顧。

Rails的擴展性(指的是滿足需求的可擴展性),和其它的Web應用框架一樣好。Mongerl讓這個工作變得非常簡單,它非常快,基於HTTP。如果你以前用過Tomcat,Resin,WebLogic或者Apache+PHP,那麼Mongrel運行Rails會達到同樣的效果。

其實我是承認Ruby的效率不高的。Ruby的社區曾經有意的忽略了「高性能」重要的議題,他們必須正視這一點。現在已經有了一些成果,可以讓Ruby 變得快一些。但是還有許多問題要解決。有一個叫Rite的VM已經展示了一些成果(或是你可以講 YARV),對Ruby的加速已經可以和Java的解決方案相提並論了。

Ruby的強項不在於它的運行速度,而是在於它的開發速度。我可以證明這一點,我在Mongrel上花了三個月的時間,它已經是一個全功能、穩定、高效的web server,可以用它來支撐許多Ruby網站。如果不用Ruby,這是不可能的。

Rails的問題又不同於Ruby,因為Rails自己有著優秀的 cache 機制,這在一定程度上彌補了Ruby的龜速。Rails用「page caching」、「fragment caching」來加速應用。如果你善加良好的規畫你的 cache 方案,你可以得到和靜態頁面一樣的性能。甚至比Java或者PHP的做得還要好。

問:那麼,商業化的技術服務呢?

答:Rails現在還做得不夠好。我也了解很多組織在投資技術之前,他們會需要商業性的支援。但是,情況會越來越好。會有越來越的資金投入到這個Rails服務領域來的,他們會像PHP類似的眾多服務一樣做得很好的。如果你看看PHP,最開始只有Zend一家在做這個服務,後來有越來越多的大公司加入到服務的行列中來。

問:在開始做Mongrel之前,你在開發SCGI,說一說它們之間的相似之處,談談他們如何 play together(or not)

答:SCGI 是我的第一次取代FastCGI的嘗試。SCGI的目的是高效率的支撐純Ruby應用,目的已經達到了。但是,SCGI在很多web server中的支持是相當有限的,並且也不是那些web server 未來開發的選擇。Lighttpd的支源發來於對它的mod_fastcgi的修改,Apache的SCGI Module來自於Apache Project之外,並且Apache聲明過他們將對FastCGI的支援要多過對SCGI的支援。事實證明,許多人在Apache上使用SCGI與多個後台通信時都遇到了麻煩。SCGI看起來似乎不妙。

Mongrel最開始是作為一個SCGI的proxy,試圖解決上面的問題。我寫了一個Http的解析器,然後用C寫了一個代理程序來回應請求,再轉發給SCGI。做到一半的時候,我意識到這個解析器寫的是如此的完美,讓我決定跳過中間轉發的部份,直接寫用Ruby寫一個web server。大約一天之後, Mongrel誕生了。

我的對SCGI的計劃是,簡化它,只滿足最基本的要求。SCGI裡面目前有許多的DRb(分布式Ruby)管理代碼,還有一些其它人使用(濫用)的片斷, 但是,這對那些只是希望使用SCGI來工作的人來說沒有一點用處。為了支持那些目前使用SCGI的用戶,我將移植一些Mongrel的發明過去,比如 thread模型。要簡化SCGI,讓它回到最初的面目上去。

說了這麼多,我想你已經明白了我未來的工作主要是Mongrel,我認為它是支持Ruby web應用的比較power的方法。HTTP 跟 SCGI 相比,在支援跟開發 Rails 來說,都是一個比較好的 Protocol。

如果有任何人對接手SCGI的工作感興趣,我歡迎。或許那家公司可以在上面開發一個更好的產品。它在RubyForge上有個專案,有興趣和有能力的人來吧,我已經準備好了交出它的管理權。

問:你在Mongrel上的工作是如何影響你在Rails上的工作的?或者相反?

答:在Mongrel中,我必須用到的Rails代碼非常的少,這是為了讓Mongrel與Rails保持比較分離的結合,這樣當Rails在某個release版中改了甚麼東西並且讓程序崩潰時,Mongrel不受影響。

當我在用Rails上開發時,我積極的使用Mongrel,並且記下哪些方面要作改進。這讓我可以保證Mongrel的實用價值,而不是為了純粹的學術目的作的憑空想像。

舉個例子,我在windows平台上做開發,那簡直是不可思義的痛苦,主要的原因不在於windows本身,而是開發Rails的人從來沒有深入的使用過windows。Luis Lavena做的許多改進讓事情變得好了些。對於我這樣的、還有其它許多貧窮的使用windows的粗人來說,我要讓Ruby on Rails更容易使用些。

問:我知道你在為Rails和Nitro camps上能運行Mongrel而努力。目前最大的障礙是甚麼?

答:最好的事情是讓Mongrel變成「跟框架保持分離」的。我是唯一的一個能Rails與Mongrel合作的人。Rails核心開發團隊的一些傢伙主要是在開發時測試Mongrel,但是我自己,Luis Lavena,其他的幾個人,幾乎做了讓Mongrel產品化的全部工作。我和Luis是唯一被期待用Rails來做產品的人。

Nitro,camping,還有IOWA團隊的人,為我做了許多讓mongrel適應他們平台上的工作。他們下載Mongrel,閱讀文檔,初期會打擾我,但是大部分時候不要我插手。 我覺得我幫助Campng項目最多,但實際上管理Mongrel的代碼要歸功於Camping。它回饋給我的是放在了0.3.12.5發行版中一個大檔案的上傳/下載 Patch,。因為他說他是在給ParkPlace做DVD的上傳/下載時碰到了。


問:Mongrel給那些使用它的項目們回報甚麼了呢?

答:我認為有兩件最大的回報,一是安全性增強,二是win32平台的支持。

Mongrel的設計考慮了大多數HTTP服務器碰到過的安全問題,這些問題來自於過於鬆散的HTTP協議手工代碼處理。Mongrel使用了一個生成處理器(使用了Ragel),它非常穩固、優秀,可以阻擋大量的網路攻擊。因為這個保護是來自於HTTP協議層的,所以使用Mongrel的任何框架都可以自由的使用它。

在EastMedia/VeriSign計畫中,我們遇到了一波來自某「安全公司」的網絡攻擊。在這裡我不想指出這家公司的名字,以免給他們做了免費的廣告。他們在沒有事先通知我們的情況下,對還沒有發布的機器,使用了一些掃描軟件。

好在Mongrel在HTTP層就阻擋了所有的攻擊,沒有費一點事就把他們踢了出去。但是就在同時,Apache卻讓這次攻擊通過了 Proxy,一點報警都沒有。

當他們進行了自動掃描之後,我們知道了有一些在「安全公司」的「手寫代碼」攻擊的人,被Mongrel所做的深深吸引住了。

最有趣的部分是,Mongrel所做的全部,是使用了一個基於文法和解析生成器(Ragel)的正確的解析器。其它web server使用人工編寫的HTTP解析器,被證明是易受攻擊的、難於與真正的HTTP1.1 RFC規範相比較,維護起來也是非常痛苦的。使用了Ragel之後讓Mongrel非常的穩固,不需要創建特殊的攻擊探測邏輯,也能阻擋這些攻擊。

其它項目從Mongrel身上得到的第二個好處,是Luis Lavena所提供的Win32支持。從Mongrel在Win32平台上成功之後,我看到了一些說Luis讓其它項目獲得了Win32平台兼容性的好消 息。有謠言甚至說Luis和它的朋友們為Win32用戶打開了Ruby世界的整個大門。我希望對Daniel Berger的win32utils項目也有同樣的幫助。

問:在Mongrel背後的一個巨大力量是它速度快、幾乎是純Ruby代碼。你作了哪些優化工作?你使用了甚麼工具?

答:我在優化C程式碼時,使用的主要工具是valgrind和kcachegrind。這兩個都是非常奇妙的免費工具。但是 Ruby在valgrind下運行得並不好。事實上,valgrind光是hello world就吐出了3萬個error。後來我轉而使用kcachegrind。

效能檢測工具我使用httperf。當我在做了一個期待著能有性能提昇的改動後,但並沒有改觀時,我就用它重新檢測一下,再做一些其它可能有用的努力。

整個過程都用了比較科學的方法。因為我從Ruby得到的有關性能的消息非常少,我只有不斷的測試、評估、調整,不斷的重復這個過程,直到確認性能指數真的提高了。使用統計學測試真正有用的地方在於,確認每一次的變動的確有了一些不同,或者至少確保沒有帶來壞處。

我當然也使用Ruby的Profilling Library,但我只是在僅有Mongrel運行的地方作非常有限的測試。當Mongrel和其它的應用框架一起運行時,這些框架有可能拖慢了Mongrel的速度,用Ruby的Profilling Library就得不到任何有用的資訊。

舉一個例子,在一個簡單的測試中,我用YAML來回應HTTP請求,我不能使用Ruby的Profilling Library,因為所有的性能訊息都是有關YAML的。Mongrel的訊息只有一丁點兒。Rails或者Camping的性能測試也同樣的情況,Profilling 吐出來有關於框架自身的性能數據多過有關於Mongrel的。

當我對性能非常敏感的時候,我使用R工具來作有計劃的性能數據分析。


問:最近,你做了許多工作比如單元測試,好讓Mongrel穩定、安全。你能解釋一下你的方法論,和你使用的工具?

答:我非常贊同OpenBSD團隊所宣稱的,安全漏洞來自於一般的缺陷,而不是來自於你在源代碼裡面找到的那些特定的「安全漏洞」。這意味著我認為我修正了我所能找到的所有安全漏洞,並且積極的對待那些潛在錯誤之後,我會在這個過程中阻止許多漏洞。

在我的所有項目中,我拼命的做到以下幾點:

1、保證程式碼盡可能的簡單。
2、在發布我的代碼之前,做Code review,持續的發現
a、“丟失的斷言”-對於輸入輸出的不正確的假設
b、“丟失的else”-沒有覆蓋到所有的邏輯分支
c、“期待它會中止”-死循環或者短命循環錯誤
d、“檢查返回值”
e、“預料之外的異常”
f、“簡單、可讀”-用可讀性強的代碼替換奇技淫巧的代碼;對複雜的代碼寫好文檔以便其它人可以理解
3、盡可能的做單元測試
4、外部的破壞性測試和性能測試。用不正確的輸入讓你的系統崩潰,高負荷,停止中間流的干擾,隨機的拆開資源。總之想盡一切辦法搞爛你的系統。
5、用戶可用性評價。我認為如果一個系統是易於使用的,安全性問題就會少一些。但是我現在沒有實例來證明我的聲明。

最終的結果,Mongrel可以在HTTP協議層阻擋海量的攻擊。這也許不能說明Mongrel是固若金湯的,但是Mongrel正在朝這條路上走。

問:Mongrel要達到的下一個目標是甚麼?

答:最近的一個工作是改進Mongrel的安裝部屬文件。日前為止還只有一個配置Lighttpd,但次我們真正需要的是在各種平台上部屬Mongrel叢集的文件。一旦這些文件完成了,佈置Mongrel會更容易。特別是那些已經使用了其它應用服務器比如Tomcat的人們。

問:你是如何對待那些Mongrel的反饋和建議的?

答:這些反饋都是非常積極的。最關心的問題,也是最值得考慮的問題。

許多人都問到了布署問題,我將用良好的文檔來解決。其它人問到了叢級的管理,我希望Bradley Taylor(來自RailsMachine.com)將要提交的叢集插件能解決這個問題。其它一些人問到了licenses,我會在FAQs中說明。

有一些頑固的問題,是關於如何處理caching和多個複雜動態web網站時的負載均衡。對於這兩個問題我目前無能為力,我會想些好點子,我希望我的下一個項目能解決「緩存問題」。

問:Mongrel有甚麼障礙嗎?

答:我得說,Mongrel的最大障礙,是讓它被人們接受成為一個 production 的平台。開發Mongrel 已經變成非常美好的事情了。我每天都從社區中收到許多來信,說一他們認為Mongrel是多麼的多麼的棒。但就是沒有一點關於使用Mongerl作巨型productiong布署的消息。我覺得在未來的幾個月裡,情況會好起來的。

問:你最喜歡的5個 library 或者框架是甚麼(標準庫中的或者社區的都行)?

答:我要說說Camping框架。它有著太多的魔力,讓我不得提到它。Mongrel從它身上得到許多代碼和思想。

我使用webgen來管理Mongrel的網站。它可以非常容易的從一組簡單的wiki格式的頁面中生成靜態網站。

我也很喜歡 Simple 這個用 Java 寫成的又小又快速的 Web Server。當我開始開發 Mongrel 時,我從 Simple 得到很多,並且採用 Simple 的 Handler 實做方式。Simple 有很多有趣的特色,像是他會去解析並且校正 response,但是儘管如此,他還是相當的輕巧跟快速。如果我要拿 Rails 來跟 Java 比較,Simple 應該是處於兩者中間的。

網路性能測試工具,我只選httperf。它是唯一的一個能夠精確的統計分析,打斷整個的request/response鏈,精確的報告socket錯誤,每一個分析項都有精確的定義,容易使用的分析工具。

我也非常的喜歡Lua語言,我把它當成Ruby的一個輕量級的替代者。它非常快,簡潔,非常容易的就能embed到其它程式中去。有著和Ruby相似的、並不陌生的語法。

問:Ruby,Rails,Mongrel和Zed,它們各自的下一步計劃是甚麼?

答:關於Ruby的這得去問Matz,Rails的要去問David。我能說的是,我希望Ruby和Rails將會是甚麼樣子。

關於Ruby,我希望看到兩個結果。第一個是它能簡單的運行在valgrind下。讓它穩定、保持簡潔還要走很長的路。第二點是集中那些致力提高Ruby效率的人們的分散力量,到Ruby1.9的VM項目上來。

對於Rails,我希望它能少些臃腫,並且我希望ActiveRecord能有一個比較像樣的的connection pool系統。對於「臃腫」這件事情,我相信DHH已經計劃著把一些東西(類似Active Web Service)移出 core 到 plugins中去。對於ActiveRecord,需要作一些重構,讓資料庫 connection pool看上去和Hibernate的一樣。這對那些按資料庫連接數付license費使用的商業資料庫使用者來說尤為重要。

Mongrel的未來看起非常光明。我將在發布第一個production版本時。像Java將每個做的很好的產品都加入一個「Enterprise Editions」的名字一樣,我會取個「Mongrel 0.4 Enterprise Edition 1.2」的名字。我也會幫助更多公司佈署 Mongrel Server,或是將 Mongrel 加入他們的新產品中。

我的下一個目標,可能是一個caching proxy服務器,目的是讓所有的動態web 程式性能更好、更快。當我在開發 Mongrel 時,我發現到 HTTP 1.1 整體的 cacheing 非常的老舊。我想我已經有一些改進的想法,並且希望能夠給很多 web application 更快的效率進步。

----

Zed A. Shaw 是一個專業的軟體開發者。他已經開發 13年程式了,並且參與的產業範圍從政府,學校,商業產品。產品的範圍包括安全,網路,網頁程式設計。他也涉獵了系統管理,產品開發,可用性研發,顧客服務。他的閒暇時間也喜歡寫自己的自傳,大家認為他實在是一個很 cool 的人。


延伸閱讀

沒有留言: