去年三月
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 社群應該反省的事情
- Ruby 執行效能不應該被輕視,雖然我也是輕視的那一群
- Win 32 社群不該被輕視
- Ruby on Rails 已經有點擁種,該是輕量化的時候了
- 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 的人。
延伸閱讀