要證明Rails的伸縮性,最好的辦法莫過於考察一個確實有效伸縮的應用程式。在這裡我們將考察三個真實應用遇到的效能問題,以及它們如何解決這些問題。
37signals開發的Basecamp
Rails就誕生於Basecamp項目。這是一個基於web的專案管理工具,它的使用者需要每月付款。Basecamp伺服器為成千上萬的使用者提供專案管理所需的功能服務。
在為Basecamp進行效能最佳化時,最大的難題在於很難使用緩衝:每個人都來自不同的公司、有著不同的許可權,因此看到的資料也各有不同。(不過從好的方面來說,只有那些擁有註冊帳號的人才能訪問Basecamp,所以不用擔心它會被Slashdot介紹而帶來一大堆未授權的使用者。)
Basecamp每天處理大約40萬個動態請求(從看到登入頁面開始算起,直到瀏覽項目記錄板,所有的請求都包含在內)。在無法做任何緩衝的情況下,這個負載量是相當可觀的。目前有兩台web/應用伺服器來處理這些請求,每台伺服器都有兩個至強2.4GHz CPU和2GB記憶體,運行15個FastCGI進程和50-100個Apache 1.3.x進程。伺服器的負荷比通常在0.5到1.5之間。
MySQL資料庫伺服器是獨立的,但37signals的另外兩個應用程式(Ta-da List和Backpack)也使用這個資料庫。資料庫裡的記錄數在十萬層級上,最大的一張表有大約50萬條記錄。雖然要為三個應用程式提供服務,但資料庫伺服器的負荷比通常在0.1到0.3之間——資料庫不是Basecamp的瓶頸所在,這是一個好訊息。如果當前的兩台伺服器不堪重負,只要再加上新的伺服器就可以解決問題,而且我們也確實這樣做了。
Robot Co-op開發的43 Things
43 Things是一個用於“追蹤人生目標”的網站。你可以在這裡寫上你的目標,譬如“我要學日語”,圍繞著這個目標撰寫blog,並閱讀別的有同樣目標的人在幹什麼。這個應用程式的一部分需要身份認證;更多的部分則是公開的,允許未經授權的使用者訪問。公開內容訪問量常有劇烈的變化;不過還好可以對它們進行緩衝。
緩衝的儲存策略採用了memcached——為了改善效能,這個網站大量使用了memcached。由於將使用者的session資料儲存在memcached中,任何一台伺服器都可以在任何時候處理來自任何使用者的請求,而不需要任何session同步措施。對於開銷較大的資料庫查詢,其結果也以ActionRecord對象的形式被序列化到memcached中,並打上適當的時間戳記。
上線三個月之後,43 Things每天處理約20萬個動態請求。它使用了兩台web/應用伺服器,以及一台專用的資料庫伺服器,三台機器都有兩個3GHz的至強CPU和2GB記憶體。兩台web/應用伺服器上分別運行著Apache 1.3.x伺服器和25個FastCGI進程。伺服器負荷比很少超過0.3,CPU空閑時間經常在80%左右。
抵押處理引擎
Rapid Reporting將他們的“身份及收入驗證引擎”運行在Rails系統上。美國1000強的抵押擔保商有80%都使用這套引擎,每月處理2百萬次抵押申請交易。
一開始,Rapid Reporting希望檢驗Rails是否能夠勝任,因此他們從10台叢集機器向一個應用程式進行壓力測試,每秒發起3千次請求。真實的應用程式大概需要每秒處理300次請求,並執行一系列的商務邏輯。此外,處理抵押業務必須遵循格萊姆-布裡勒法規(GLBA),因此很多地方都需要檢查授權許可、產生查賬索引。
應用程式使用PostgreSQL作為資料庫,lighttpd作為web伺服器,每台應用伺服器運行大約10個FastCGI進程,在一台虛擬伺服器上用IP隧道技術實現負載平衡(參見http://www.linuxvirtualserver.org/VS-IPTunneling.html)<!--[if !supportFootnotes]-->。使用這種部署方式,就可以隨時增減FastCGI進程,而不必重啟web伺服器。由此又可以實現進程管理的自動化:用一個守護進程監視負載情況,當負載達到峰值時分配更多的FastCGI進程。
這是一個真正的商業應用。這些東西聽起來也許很乏味,但是否瞭解它們也許會決定你是否能夠得到客戶的認可。