Ruby on Rails案例學習:ChangingThePresent.org

來源:互聯網
上載者:User
五個月前,Arvato Systems公司找到我說:
  • 有一個重要項目要我領導。
  • 可以使用我喜歡的技術。
  • 團隊成員(至少部分)可以由我挑選。

對了,他們還告訴我,這個項目的成果可以改變整個世界!我以前被這種事情騙過,但這次,我相信它是真的。在本文中,我將向你講述這個項目非凡創意背後的技術細節。但首先,我得讓你知道它的名字——ChangingThePresent.org。這個網站瞄準了每年2500億美元的禮品市場。以往,我們無非是送人水果蛋糕或一雙毛拖鞋,而通過ChangingThePresent,你可以送出更有意義、讓人難以忘懷的禮物,比如癌症研究人員的一小時時間、一英畝雨林的保有權等等。它讓送禮更為方便,而且有自己的盈利模式;但最讓我驚訝的是,這個創意改變了人們的思維方式。
背景如果你對非盈利組織有所瞭解,那麼就能大致猜到ChangingThePresent的運作模式。就使用的技術而言,它和其他需要通過互連網聚集使用者的行業別無二致。但在ChangingThePresent,人們彼此不再是買賣關係,而代之以捐贈和無利可圖。在蘭斯·阿姆斯特朗基金會、兒童救助協會、第一本書(First Book,美國貧困兒童讀物捐贈機構)和Sierra俱樂部(Sierra Club,美國自然保護群組織)等將近200個顧問機構和380家非盈利組織的支援下,ChangingThePresent的市場運作工作正在走上正軌。但在這裡,我更想告訴你的是這個項目技術方面的故事。
在本文中,我將帶你重溫我們使用Ruby on Rails開發此網站的整個過程。你將瞭解我們用到的一些關鍵特性和常用外掛程式。我們使用的技術並非驚世駭俗,但對我們每天所做工作有所瞭解,可能對你有所協助。我的目的是在團隊協作、生產環境下的可信任技術、我們使用的工具,以及我們認為非常重要的Rails架構等方面,讓你有個大致認識。我還會提供一些連結資源,但不會就具體問題作細節探討,如果你希望深入瞭解,可在文後留言。如果你們真有興趣,我將樂於撰寫系列文章,就你們的問題共同深入討論。
概述最早的時候,我以個人身份加入了這個團隊,擔任主程式員。因為可擴充性和穩定性優異,團隊領導人首選Java,但以此評估整個解決方案後,發現投入巨大且系統複雜。我們後來盯上了Ruby on Rails,它很好兼顧了高效生產力、編程模型的清晰度和運行效能。當然,它也並非萬無一失。仔細分析現有的網站和我們的商業計劃後,我們覺得自己有能力設計出每天處理數百萬請求量的系統。儘管當然還沒有這樣的成功案例,但我們認為通過彙總緩衝(Aggregation Cache)和無共用群集(Shared-Nothing Cluster)技術,可以開發出如此層級的系統。
9月份來了又去了。我們的工作非常高產,每周都能推出Demo,進展神速,市場開始關注此項目。到11月份,我乾脆加入了WellGood LLC公司,並擔任CTO。12月間,我們發布了網站的第一個Beta版。Rails為我們生產力的提高和最後的成功起到了至關重要的作用。
我們離整個網站的完工還差得很遠——到目前為止,已經完成的功能大概只佔原計劃的5%——但我們已經有了足夠積累,相信後來的工作會越來越順利。儘管我們已經初步做過基準和壓力測試,但仍然無法保證現在的版本能夠長期應對訪問量的增長,因為幾乎沒有哪個Rails網站提供了先例。但我們在以下幾個方面大有信心:

  • 我們可以實現快速開發、測試和發布。
  • 在少量硬體的支援下,我們就可以將系統擴充到更高訪問量級。
  • 我們可以根據實際需要,在不修改軟體系統的前提下增加硬體。
  • 我們的五人Team Dev在網站早期成長過程中可以同時完成開發和管理工作。
  • 我們可以解決未來可能出現的擴充性和效能問題。

就上述幾個方面而言,對我們來說最重要的還是生產力。我的團隊必須走在競爭者前面,以最快速度滿足使用者和投資人的需求。本文的剩下部分主要從技術角度介紹我們的一些做法,對於本文難以說清楚的問題,我會提供資訊連結。
拓撲結構首先,讓我們對系統全貌有個大致瞭解。Rails應用大多採用LAMP(Linux+Apache+MySQL+PHP)架構。就此網站而言,我們使用了Sun的硬體,以F5 BigIP作負載平衡。和其他很多新興Rails網站一樣,我們的應用伺服器是Mongrel(主要處理動態內容。和lighttpd 屬同類產品),資料庫自然是MySQL。我們的資料庫按master/master/slave模式部署,以滿足故障切換(Fail-Over)、效能和擴充性要求。
我們選擇了對大流量Rails網站運營有著豐富經驗的Text Drive公司託管我們的內容。和其他互連網網站一樣,我們主要是唯讀流量,寫流量主要集中在幾個社交網路個人化模板,以及使用者購物曆史上。我們還通過分析發現ActiveRecord模型需要最佳化,關鍵是要減少資料庫請求次數。此外,我們還利用MemCache外掛程式實現了緩衝策略。除緩衝層外,我們採用的都是Rails傳統配置策略。
每個捐贈者滿懷熱情來捐贈,他們常常會為贈品準備很多圖片。接受捐贈的機構和組織也會從中挑選能最恰當展示贈品的圖片,以激發訪問者的興趣。圖片的價值無容質疑,通過圖片的推介,可讓贈品儘快到達最需要它們的人手中,從而增強捐贈者的信心和自豪感。但大量圖片下載,無疑加大了伺服器的負擔。Mongrel的特長不在於靜態內容,所以我們採用了URL重寫(URL Rewriting)技術管理圖片。目前,我們還正準備利用Panther Express實現圖片緩衝,加快訪問速度。
一些Java和.NET的開發人員及相關廠商警告我們說Ruby on Rails可能無法滿足我們在擴充性上的要求,但我們對此並不十分擔心。我相信軟體技術發展這麼多年,已經積累了大量對Rails同樣適用的經驗教訓;Rails的基石LAMP也是目前各類大型Web網站的主流架構準則。對我來說,更重要的問題是如何以最快的速度實現投資人、使用者和老闆的需求。現在,我更多的時間花在團隊、工具和實現過程等方面。
過程與團隊Rails宣稱:“我們敏捷,我們快樂。”對此我完全贊同,我熱愛敏捷開發。我們熱烈擁抱以下敏捷準則:

  • 我們專註於縮短開發週期,堅持周周迭代。我們至少每周發布一個新版本。
  • 我們依靠開發人員邊開發邊編寫測試案例,而不是漏鬥式階段測試保證品質。
  • 我們不害怕以最佳化業務模型的系統重構。通過重構,我們提高了代碼品質、需求理解準確度和系統靈活性。
  • 對次級需求,我們實行周內管理;對重要需求,我們實行月度管理。
  • 我們利用每周發布的Demo,與使用者保持緊密聯絡。

我們利用Trac/SVN執行原始碼原理、需求跟蹤和發布計劃管理。Trac和SVN的高度整合給我們的工作帶來了極大方便。在重量級自動化測試和輕量級人工測試後,我們根據測試結果漸進式修改我們的產品,並對重要修訂實施分支管理。使用Rails平台,通常不需要我們做大的修訂。
我們的團隊成員分布在三個時區,不久可能更為分散。成員間可以隨時開放交流,這樣可以儘快解決問題。雖然要依靠長距離通訊,我還是希望我的團隊裡有更多的優秀Rails開發人員,而不是工作地雖近,但新手過多。到目前為止,這個決定的好處是顯而易見的。我們還儘可能增加會議次數,縮短會議時間。我們每天通過Skype舉行例會,每周召集市場人員參加的技術會議。我們還堅持每周公布階段性計劃。
有人說Rails對複雜解決方案的擴充支援能力不夠,我不贊成這種說法。和同類技術相比,Rails的生產力是最高的。Rails對我們的開發過程、團隊組建和管理都產生了戲劇性的影響。所用技術的生產力越低,迭代周期就越長;團隊越大,花在檢查和協調上的時間就越多——在Ruby和Java專案管理我都經曆過後,更為支援這個觀點。使用別的技術,就需要組建更大的團隊(比如10到15人),而我們則可以保持團隊最小化。我們目前有5個Ruby開發人員,最多隻需要其中兩個人專門負責HTML設計。以後可能增加到7人更為合適,那時,我們將擁有第二個開發小組,專門負責複雜和重點問題的解決。
工具我們使用的工具超級簡單,比如代碼覆蓋測試使用RCov,整合測試使用Selenium,驅動所有的測試和覆蓋工具的則是Rake。我們的測試案例覆蓋率一般在85%左右,特別是嚴格跟蹤覆蓋率後,基本保持在79%到90%的範圍。因為我們經常修改使用者介面,所以Selenium的使用方式不太理想。但我想使用者介面逐漸固定下來後,成功率會慢慢提高的。目前,我們主要進行的是單元和功能測試,但在其他測試方法探索方面也取得了較大進步。
我們的開發人員可以自由選擇編碼工具,實際上到目前為止,我們沒有任何人從頭至尾使用過整合式開發環境。我們主要使用的原始碼編輯工具是TextMate。包含了日誌和測試功能的Rails基準和調試工具已經有足夠能力協助我們完成系統調試。重構有點傷腦筋,特別是必須修改資料庫模型的時候,因此一旦發現有足夠好的IDE,我們還是會考慮使用的。不過,就我的經驗而言,我覺得我們現在的維護速度可以達到Java應用的三倍,甚至更快。
核心架構儘管在項目方案的選擇上,我們最初顯得有點兒激進,但現在最重要的是一如既往、繼續堅持。我們的核心架構仍將以Rails為中心。在資料庫端,我們是DHH(譯者註:Rails作者David Heinemeier Hansson的簡稱)的忠實信徒;不強行要求參考完整性等資料庫約束,也沒有使用資料庫檢視。在測試方面,我們主要依靠Rails架構;當然,隨著測試案例規模的增大,我們也在積極嘗試其他工具。不少方面都還不到最後定論的時候,仍在探索和變化之中。但總體而言,我們使用的是REST WebService支援下的經典Rails MVC模型。下文對此還將詳述。
模型和很多網路社區網站一樣,首先對讀操作做了最佳化,因為我們的大部分內容都是靜態,平均而言每天修改不到一次。通過分析競爭者的統計資料,我們發現,要想提高系統容量,對穩定內容的緩衝非常重要,像慈善組織(如UNICEF。譯者註:United Nations Children's Fund,聯合國兒童基金會)、贈品(如癌症研究者的一小時時間)及機構使命(如世界和平、醫學研究等)。這些內容不會頻繁變化,可以穩定緩衝。我們使用Rails外掛程式ActsAsCacheable實現了靜態內容的緩衝。其後端部署了分布式的二級快取服務(MemCache),但在特殊情況下,我們絕大多數時候會直接使用ActiveRecord API。
此網站也包含工作流程機制。比如,慈善機構提交了某項內容,ChangingThePresent的管理員將負責內容的審查和批准。我們必須提供可在任何時候將任何贈品啟用和凍結的功能;而且我們更喜歡將記錄標記為刪除狀態,而不是直接從資料庫刪除。為了支援這種自訂的工作流程,我們引入了一個叫做ActsAsStateMachine的外掛程式。此外掛程式支援使用DSL(Domain Specific Language)表述狀態機器,有關DSL的詳細資料請參看:跨越邊界:Rails外掛程式。
知道DSL被用於和我們的商業使用者交流,我才認識到DSL的強大。Ruth Ann Hacking負責網站內容搜集與管理。雖然她沒有編程經驗,卻是一個參加過世界盃的擊劍手。因為她隨時可以用軍刀(甚至一支圓珠筆)殺死我,所以我整天想法設法給她找樂子。一次興起,我將包含狀態機器的代碼給了她。結果出人意料,她居然將代碼從頭到尾看完了,還找出了幾個Bug!Ruth Ann高興了,我也活到了現在。這就是和Rails在一起的生活,它的架構裡總隱藏著一些小東西,時不時跳出來逗我開心開心。
使用者介面我們的使用者介面構建於經典的Rails控制器-視圖-布局(Controller-View-Layout)模式基礎上。現在還不支援新的RESTful控制器,但會在以後考慮增加。我們只在少數地方使用了AJAX——如賀卡產生嚮導和現場編輯。總而言之,我們的目標是讓使用者介面儘可能簡潔明了。為了提高網站的可擴充性,我們採取了如下措施:

  • 盡量少用圖片。比如網站中有很多圓角,我們都是用JavaScript庫實現渲染。當然,不久實現對PantherExpress的支援後,這一策略將有所改變。
  • 減少頁面緩衝。在我們的網站中,使用者自訂的東西很多,所以靜態頁面很少,頁面緩衝的價值不大。目前緩衝主要實現在ActiveRecord層面,另外使用PantherExperss實現圖片緩衝。
  • 我們最開始以翻頁方式,按名稱首字母排序向使用者展示贈品。但不久發現所有使用者都只能從A開頭命名的贈品開始瀏覽體驗,於是修改為隨機排序方式,並每天緩衝結果。我們沒有通過視圖實現這個功能,而是利用MySQL隨機函數設計了一個使用者自訂的、以目前時間為隨機種子的搜尋器。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.