posts - 262,  comments - 221,  trackbacks - 0
          原文鏈接:http://www.iteye.com/topic/1058510

          用rails3做目前的這個網(wǎng)站項目,已經(jīng)有半年多了。我們這個團(tuán)隊?wèi)?yīng)該算是比較早使用rails3做項目的,3.0正式版剛發(fā)布就開始嘗試了,在項目開發(fā)期間針對很多問題也做了一些探索。談不上經(jīng)驗,更稱不上最佳實踐,只是分享出來,經(jīng)學(xué)見易,道家見淫,有需要的朋友各取所需。小公司小項目,適用于初中級用戶,大牛們可一笑而過。

          1、網(wǎng)站需求

          財經(jīng)資訊網(wǎng)站,向用戶提供財經(jīng)金融資訊,發(fā)布和宣傳公司研發(fā)的各種金融產(chǎn)品,引導(dǎo)用戶注冊和購買產(chǎn)品。當(dāng)前網(wǎng)站的內(nèi)容來源是公司的資訊平臺和行情數(shù)據(jù)庫,通過http接口和oracle sql獲取數(shù)據(jù)并展現(xiàn),可能在中短期會有用戶互動和用戶原創(chuàng)內(nèi)容(UGC)的需求。

          在可預(yù)期的未來,即2到3年內(nèi),預(yù)計流量將達(dá)到10-100萬PV/天。因此在進(jìn)行設(shè)計時,以該流量作為本架構(gòu)能夠承載的上限。如果網(wǎng)站真的有幸活到了幾百萬PV以上的流量,那肯定就不缺錢了,凡是錢能解決的問題,都不是什么大問題。

          2、架構(gòu)設(shè)計

          根據(jù)預(yù)計流量,在可預(yù)期的時間階段,結(jié)合該項目的運營要求和預(yù)算成本,網(wǎng)站主要以高可用(HA)和有限的水平擴展性(scale out)為核心架構(gòu)理念,采用分布式無共享架構(gòu)(distributed share nothing architecture),使用rails默認(rèn)的cookie_store機制來持有和處理session,消除了有可能成為性能瓶頸的集中式session的缺點。而且在架構(gòu)設(shè)計時,使得系統(tǒng)負(fù)載盡量平均分配到每臺服務(wù)器上。

          單臺服務(wù)器如同XX的承諾,永遠(yuǎn)都是靠不住的。單臺服務(wù)器會死機、掉電、停轉(zhuǎn)、拔線,所以在架構(gòu)中盡最大可能避免每個功能組的單點故障,做到在服務(wù)器集群中,任意一臺服務(wù)器失效,或幾臺不相關(guān)服務(wù)器同時失效,網(wǎng)站仍可正常運行。而且無單點故障的架構(gòu),服務(wù)器可隨時重啟,也有利于操作系統(tǒng)的內(nèi)核升級和安全補丁等日常維護(hù)工作。經(jīng)過這幾個月的連續(xù)使用,各種原因的幾次單點故障均沒有影響到網(wǎng)站正常服務(wù)。

          在數(shù)據(jù)庫的使用上,考慮到傳統(tǒng)的關(guān)系型數(shù)據(jù)庫已不太適應(yīng)當(dāng)前互聯(lián)網(wǎng)應(yīng)用的海量數(shù)據(jù)和高負(fù)載特點,因此mysql只起到關(guān)鍵數(shù)據(jù)存儲作用,利用事務(wù)性和成熟性,保證網(wǎng)站數(shù)據(jù)的完整和安全。然后加入非關(guān)系型數(shù)據(jù)庫redis和mongodb,作為數(shù)據(jù)冗余存儲和計算中心,承載絕大部分的高負(fù)載數(shù)據(jù)請求,可有效減小mysql的壓力。這樣就不必費心配置復(fù)雜難用的可擴展mysql集群,使用單臺mysql服務(wù)器即可承載較高的網(wǎng)站流量。而redis和mongodb天生就是為互聯(lián)網(wǎng)應(yīng)用設(shè)計的,它們的集群配置和水平擴展相對更為簡單方便。聽說現(xiàn)在已經(jīng)有團(tuán)隊只使用mongodb來作為網(wǎng)站數(shù)據(jù)庫,向他們的前衛(wèi)和勇敢,致以我們團(tuán)隊深深的敬意。



          2.1 軟硬件平臺
          當(dāng)前正在運行的硬件是6臺dell 2U二手服務(wù)器,總價大約在1.6萬,物美價廉,居家必備。目前使用良好。另外借公司發(fā)展東風(fēng),已有8臺全新dell刀片進(jìn)入機房,正準(zhǔn)備把全部系統(tǒng)遷移至新服務(wù)器上。

          服務(wù)器操作系統(tǒng)使用ubuntu server 10.04.2 x64,正在測試11.04,如可用并有益,則有可能在新硬件上安裝使用。11.04官方支持到2012年12月份,對人類來說已經(jīng)足夠。2012之后,所有服務(wù)器已不復(fù)存在。

          2.2 高可用方案。核心組件采用keepalived,使用master-backup機制來實施主備服務(wù)器的實時切換。

          2.3 負(fù)載均衡
          根據(jù)網(wǎng)站流量和實際需求,使用nginx作為七層交換,把前端進(jìn)來的用戶請求round-robin到后端的應(yīng)用服務(wù)器。nginx支持容錯轉(zhuǎn)移,如果后端的某臺應(yīng)用服務(wù)器失效,nginx可把該臺服務(wù)器暫時移出可用列表。

          同時,由于負(fù)載均衡服務(wù)器位于整個網(wǎng)站系統(tǒng)的最前端,一旦失效則整個網(wǎng)站立刻癱瘓,所以其重要性無與倫比。為保證高可用,使用keepalived實現(xiàn)雙服務(wù)器的故障實時切換。

          2.4 應(yīng)用層。使用ree+passenger+nginx作為rails web服務(wù)器,passenger易于管理維護(hù),而且和ree配合較好。所有應(yīng)用服務(wù)器地位均等,每臺服務(wù)器均發(fā)布完整的項目代碼,不在功能上做分布式,以利于維護(hù)。

          2.5 數(shù)據(jù)庫。使用2臺mysql,做master-master復(fù)制,配合keepalived實現(xiàn)高可用。

          2.6 緩存系統(tǒng)
          緩存系統(tǒng)分為一級緩存和二級緩存。一級緩存用于存儲數(shù)據(jù)量不大,但對速度要求高的緩存數(shù)據(jù)。二級緩存用于存儲對速度要求相對較低,但存儲量巨大的數(shù)據(jù)。

          一級緩存使用內(nèi)存數(shù)據(jù)庫redis,優(yōu)點是速度快,并發(fā)高。用于存儲首頁緩存數(shù)據(jù),保存股票行情數(shù)據(jù),以及配合redis-store作為rails默認(rèn)頁面緩存,等等。目前存儲數(shù)據(jù)約2800條,使用內(nèi)存100M。

          二級緩存使用文檔型數(shù)據(jù)庫mongodb,優(yōu)點是查詢功能強大,支持海量存儲。用于存儲部分資訊內(nèi)容,提高頁面響應(yīng)速度。目前存儲數(shù)據(jù)約10萬條,數(shù)據(jù)文件大小為4G。

          2.7 文件系統(tǒng)。使用glusterfs,以其自身的機制可實現(xiàn)雙機熱備和單臺服務(wù)器失效返回后文件的自動同步。用戶上傳的文件會自動地同時保存于2臺glusterfs服務(wù)器上。對應(yīng)用程序來說,它們只是將文件保存于本地某個指定目錄,glusterfs對應(yīng)用是透明的。而且任何一臺服務(wù)器單獨失效都不會對用戶產(chǎn)生可察覺的影響,失效的服務(wù)器返回后,glusterfs會計算2臺服務(wù)器所保存文件的差別,對改動過的文件進(jìn)行同步。

          2.8 異步和定時執(zhí)行。使用resque作為基礎(chǔ)架構(gòu)執(zhí)行異步任務(wù),以resque-scheduler執(zhí)行定時任務(wù)。同樣,也以雙機互備來保證無丟失地產(chǎn)生和執(zhí)行任務(wù)隊列。經(jīng)過這幾個月的使用,除了解決了一些與其它系統(tǒng)交互時意外的隊列堵塞問題,目前看來resque還是值得信任的。

          3、技術(shù)選型

          在技術(shù)路線上,團(tuán)隊擁有最大的自由度,因此我們可以按照自己的理念進(jìn)行技術(shù)布局,而且可以大膽地使用最新的技術(shù)架構(gòu)和解決方案,在完成公司開發(fā)任務(wù)的同時提高團(tuán)隊技術(shù)水平,緊跟業(yè)界技術(shù)潮流。

          3.1 網(wǎng)站使用rails 3開發(fā),用到的主要組件和版本如下。未注明版本號的,為最新版本。
          Ruby代碼 復(fù)制代碼 收藏代碼
          1. rails 3.0.7    # 基礎(chǔ)平臺   
          2. rake 0.9.0  gem 1.7.2  bundler 1.0.13    # 基礎(chǔ)工具   
          3. mysql2 0.2.7  ruby-oci8  activerecord-oracle_enhanced-adapter    # 數(shù)據(jù)庫驅(qū)動   
          4. nokigiri  yajl-ruby    # 解析器   
          5. authlogic  cancan    # 權(quán)限和驗證   
          6. ckeditor  paperclip  rmagick    # 編輯器和圖片   
          7. redis-store 1.0.0.beta5  mongoid 2.0.2    # nosql   
          8. resque  resque-scheduler  eventmachine    # 異步和定時任務(wù)   
          9. capistrano  capistrano-ext    # 代碼發(fā)布   
          10. open-flash-chart  formtastic  rspec    # 雜項  


          3.2 數(shù)據(jù)庫。使用mysql 5.1。因為5.5取消了在文件中配置replication,只能手動命令執(zhí)行,個人感覺比較麻煩,不能做到服務(wù)器的無人值守。如果有同學(xué)找到了5.5自動配置的方案,還望賜教。謝謝。

          3.3 redis 2.2.7。因為官網(wǎng)說redis原生的cluster方案,有可能將在2011年6月才出RC版,所以目前我們使用redis的master-slave機制,自己寫了一個監(jiān)控腳本,配合keepalived,實現(xiàn)兩臺redis服務(wù)器之間的數(shù)據(jù)同步(replication)和容錯轉(zhuǎn)移(failover),以此來達(dá)成高可用。

          3.4 mongodb 1.8.1。mongodb自身有原生的replset方案來實現(xiàn)數(shù)據(jù)同步和容錯轉(zhuǎn)移,因此在mongodb的層面直接使用該方案,配置2臺服務(wù)器即可實現(xiàn)高可用。

          3.5 glusterfs 3.1.1。使用原生的雙機互備方案。

          4、項目管理

          第一期的開發(fā)從2010.11開始,到2011年元旦上線,大致為2個月的時間。上線后又經(jīng)歷了大概1個月,基本穩(wěn)定達(dá)到目前的狀態(tài)。純代碼約1萬行。開發(fā)人員4名。開發(fā)平臺有ubuntu desktop和windows 7,開發(fā)工具有aptana、netbeans、emacs等。對平臺和工具不做要求,在dos下能把活干好,也行。

          4.1 源碼管理。使用git,采用所謂的“穩(wěn)定分支模式”。有3個主要的分支:master、alpha、production。源碼合并的順序一般情況下是master -> alpha -> production。master用于日常開發(fā),alpha用于發(fā)布測試版本,production用于發(fā)布生產(chǎn)環(huán)境的正式版本。如果有hotfix或者feature的需求,再另開其它臨時分支。每個開發(fā)人員對所有分支都擁有全部讀寫權(quán)限,使用公鑰認(rèn)證的ssh訪問源碼庫。

          4.2 發(fā)布管理。使用capistrano作為發(fā)布工具,結(jié)合capistrano-ext的multistage功能對多個不同的發(fā)布環(huán)境進(jìn)行管理。并且結(jié)合了bundler的capistrano模塊對bundle gems進(jìn)行發(fā)布時的自動安裝管理,做到了測試版本和正式版本的一鍵化發(fā)布。在99%的情況下不需要登錄服務(wù)器另外做配置或修改。

          4.3 項目管理。使用redmine作為項目管理平臺,可以和git庫有機地結(jié)合起來。

          4.4 測試。由于大部分功能都是調(diào)用其它平臺或訪問行情數(shù)據(jù)庫,邏輯比較簡單,因此rspec用得不太多,僅在支付接口等部分商業(yè)邏輯上使用。這是項目目前的一個缺陷,以后會著意加強測試方面的代碼量。

          5、未來擴展

          5.1 負(fù)載均衡的性能取決于接受請求的那臺服務(wù)器的性能,nginx的并發(fā)還是令人放心的。即使以后性能成為瓶頸了,可以用更好的服務(wù)器,或者換硬件交換機,直至F5。

          5.2 應(yīng)用層的擴展比較簡單,只需增加應(yīng)用服務(wù)器節(jié)點即可。負(fù)載均衡的nginx可以設(shè)置權(quán)重以平衡負(fù)載。

          5.3 mysql不太好擴展,但如前面所言,把負(fù)載盡量分散到nosql上,在百萬PV級別,mysql也就無需擴展了。實在要擴展,可以嘗試做讀寫分離等方案,或等待幾年后mysql搞定更漂亮的水平擴展方案。

          5.4 redis和mongodb都比較方便水平擴展,多加服務(wù)器,做集群配置,即可分散流量提高負(fù)載。

          5.5 glusterfs也具備水平擴展能力,再與nginx結(jié)合直接輸出文件,可承載較大流量。


          項目基本架構(gòu)就是如此,限于篇幅,很多地方都是一帶而過。下一步我準(zhǔn)備寫如下內(nèi)容,留作個人積累和公司文檔,包括但不限于:

          1、keepalived的配置和使用,優(yōu)缺點。
          2、rails 3的優(yōu)點,個性化設(shè)置,存在的缺點和臨時解決方案。
          3、redis和mongodb的主從復(fù)制架構(gòu),相關(guān)問題的解決方案,各自的特點和基礎(chǔ)使用。
          4、glusterfs的配置和使用。
          5、resque系列組件的使用,異步和定時任務(wù)執(zhí)行。
          6、測試和產(chǎn)品多環(huán)境下的capistrano一鍵發(fā)布系統(tǒng)。

          如果有朋友對此感興趣,我會選一些發(fā)上來。沒興趣的話我就據(jù)為己有了。


          -------------------------------------------------------------
          生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
          posted on 2011-05-27 16:47 Paul Lin 閱讀(863) 評論(0)  編輯  收藏 所屬分類: RoR
          <2011年5月>
          24252627282930
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          常用鏈接

          留言簿(21)

          隨筆分類

          隨筆檔案

          BlogJava熱點博客

          好友博客

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 建昌县| 合江县| 本溪市| 科技| 绿春县| 百色市| 繁峙县| 津南区| 中山市| 尼玛县| 高尔夫| 清流县| 津市市| 德令哈市| 安图县| 富阳市| 聊城市| 濮阳县| 湖北省| 鄢陵县| 宁津县| 瓦房店市| 务川| 黄陵县| 衡阳县| 柘荣县| 安义县| 海晏县| 浦北县| 文登市| 八宿县| 白山市| 马边| 茌平县| 大方县| 时尚| 肇东市| 汕头市| 宽城| 桐庐县| 虹口区|