jinfeng_wang

          G-G-S,D-D-U!

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks

          寫在前頭

          靜態(tài)化是解決減輕網(wǎng)站壓力,提高網(wǎng)站訪問速度的常用方案,但在強調交互的We2.0 時代,對靜態(tài)化提出了更高的要求,靜態(tài)不僅要能靜,還要能動,下面我通過一個項目,談談網(wǎng)站靜態(tài)化后的架構設計方案,同時和大家探討一下,在開源產(chǎn)品大行其道,言架構必稱MemberCache, Nginx,的時代,微軟技術在網(wǎng)站架構設計中的運用.

          靜態(tài)化的設計原則和步驟

          靜態(tài)化是解決減輕網(wǎng)站壓力,但是靜態(tài)化也會帶來一系列的問題,包括開發(fā)上復雜度的增加,維護難度的增加,運用不的當,更可能適得其反,而許多替代方案,比如頁面緩存,如果運用得當,也能起到很好的效果,所以在開始之前,必須進行詳細的考察,確定是否適合靜態(tài)化,并制定適合的靜態(tài)化方式,下面先介紹一下

          l         考查讀寫比:

          讀寫比,準確的說是讀寫負荷比,是否值得靜態(tài)化的最終考慮,由于一般寫入的壓力明顯大于讀出的壓力,如果寫入太頻繁,或者每次寫入消耗的資源太多,都不能達到效果,我覺得讀寫比例10:1應該是個上限.具體情況需要根據(jù)自己的業(yè)務邏輯判斷

           

          l         確定頁面呈現(xiàn)的內容是否適合靜態(tài)化:

          在設計方案時,必須詳細考慮每個原型頁面,找到頁面上展示的信息,和他的更新方式,更新時機,更新頻率,一定要注意那些不起眼的信息,他們可能左右你的設計,

          比如:我們以CSDN的論壇的任意一篇帖子為例,進行分析

          上面的帖子中呈現(xiàn)的內容主要是這樣幾塊,帖子內容,回復內容,發(fā)帖人回復人的用戶信息

          n         帖子內容和回復內容在發(fā)帖時更新,發(fā)帖后用戶可以修改其內容,更新頻率高

          n         用戶信息,用戶修改個人信息時可能會發(fā)生更改,用戶等級增加時也可能發(fā)生更改,比如加星,更新頻率低

          n         回復數(shù)將每次回復后都要更改,更新頻率高

          n         設計時要注意細節(jié),如上圖中圈出來的部分,這些部分是怎么修改的,頻率有多大,一個都不能放過.

          l         確定生成方式:

          在上面帖子一例中.每次更改都重新生成頁面是不可取的,一篇比回復數(shù)多的帖子,需要的數(shù)據(jù)量是巨大的(每層樓的用戶信息,回復內容),任何修改,都需要重新取出數(shù)據(jù)進行生成是不能允許的.一般除非你的頁面基本不用更新,或者更新開銷極小,(比如一段嵌入的廣告代碼)才能采用整體更新的方式,不然就需要我們找到合適的更新頁面局部區(qū)域的方法:

          一般有下面兩個方法:

          1)      正則修改法:

                  比如,如果帖子中的回復數(shù),html代碼是這樣
                  <label>回復數(shù)<var id="replyCount">34</var></label>
                  我們可以通過用下面正則來查找并替換計數(shù)
                   (?<=id="replyCount">)"d{1,}

          2)      頁面區(qū)域分塊:

          把頁面分成很多小塊,在顯示時組裝起來,比如DotText就采用這個方法

          這是一篇典型的Dottext blog頁面,其中紅色標定部分是一個獨立的文件,而黃色框內的是腳本動態(tài)加載,這些部分在最終顯示的時候組合起來,最終構成了一篇Blog,具體的組合方法也有多種,可以使用Include,也可以自己來實現(xiàn).DotText就自己實現(xiàn)了一套加載機制

           

          上面的兩種方法并不孤立,并可以根據(jù)需要,配合使用

           

          l         確定需要動態(tài)加載的信息:

          頁面上總有一些內容看起來不太適合靜態(tài)化,最典型的是一些統(tǒng)計結果,比如如果你在做一個圖書介紹頁面,可能就會需要展示圖書的當天綜合評分,或者書籍排名,這些內容需要用腳本進行動態(tài)加載

          既然做了靜態(tài)化,就是希望減少服務器負載,動態(tài)加載的數(shù)據(jù)總是不得已而為之,有的時候在需求允許的情況下,我們在數(shù)據(jù)在實時性和性能方面做一些妥協(xié),比如上面帖子中的用戶星級和昵稱,從數(shù)據(jù)實時性上說,當用戶的星級增長,他發(fā)言的所有帖子都應該發(fā)生變化,所以應該用動態(tài)加載.然而其實上這些信息如果不發(fā)生變化,也無傷大雅,用戶反而能夠看到自己在多年前發(fā)帖時的級別和昵稱.

          現(xiàn)實中的項目

          X網(wǎng)站是大型的電影資訊,電影社區(qū),向外提供電影相關信息服務,以及用戶社區(qū),其中信息服務部分, 其中大部分頁面屬于信息呈現(xiàn)頁,讀取量比較大,百萬級別pv,信息主要由編輯在后臺發(fā)布,更新較少,但其頁面上有大量的交互性的內容,比如評論,收藏列表,同時許多內容允許用戶創(chuàng)造,比如上傳圖片,添加注釋.交互內容的數(shù)量和交互的頻繁程度,都超過了普通的咨詢頁面,這次調整,準備將其中訪問量最大的幾塊:電影資料頁,影人資料頁,進行靜態(tài)化,如果成功,還將運用到更多的頻道,基本實現(xiàn)全站靜態(tài)化

           

          通過對頁面設計和前一版本的分析,下面是具有挑戰(zhàn)性的地方.這些特點基本使用于大多數(shù)web2.0的站點,很具有典型意義

           

          l         頁面生成的觸發(fā)條件復雜

          一般論壇中的帖子或者blog,更新方式比較單一:主要是由回復進行觸發(fā)還有少數(shù)的修改動作,然而該網(wǎng)站一個頁面上需要根據(jù)不同觸發(fā)條件就有20多個, 比如光二級菜單:用戶發(fā)布圖片,刪除圖片,發(fā)布或者刪除影片信息,發(fā)布或者修改視頻,后臺修改電影信息,都有可能觸發(fā)

           

          l         一個動作觸發(fā)生成的頁面可能很多而且相互交疊

          每一個動作都會觸發(fā)一系列的生成,并且不同動作可能都會涉及同一個頁面或者區(qū)域的生成.

          比如:用戶給一步電影評分,需要生成評分更多頁,評分統(tǒng)計更多頁,首頁右側誰還關注此影片小區(qū)域,等等.用戶收藏一個影片,也需要更新首頁右側誰還關注此影片小區(qū)域

           

          l         觸發(fā)頻繁:

          雖然不及某些更大規(guī)模的網(wǎng)站,但是由于涉及眾多用戶參與的內容,評論,收藏等等,觸發(fā)點多,發(fā)生頻度相當頻繁

           

          l         頁面多,結構復雜,空間占用大:

          通常,需要生成的頁面規(guī)模是這樣粗略估算的,Rn*P,Rn為資源數(shù),P為每個資源的頁面數(shù),所謂資源,可以看做一個生成單位,其頁面數(shù)可以簡單看做發(fā)布一個資源,就需要生成其所有相關頁面數(shù)量,比如:發(fā)布一個blog,就需要生成一個Blog,同時還需要生成或者更新個人主頁的blog列表,算上個人主頁右側的分類文章數(shù)的小塊,也就是最多10來個頁面或者區(qū)域,但是發(fā)布一個電影,其相關的頁面至少有50個以上,而且有的頁面還帶有分頁,一個信息比較豐富的電影,其頁面竟可以達到千個以上,空間10~20M,而且資源總數(shù)也不少,電影80000左右,電影人雖然P值較少,但是總量確有幾十萬之巨,估計靜態(tài)頁面磁盤占用量幾百個G

           

          l         向下兼容

          這是一個已有系統(tǒng),舊系統(tǒng)的框框需要突破,但又沒有時間,或者不能完全突破,比如Url,已經(jīng)被收錄到搜索引擎,就不能隨便調整,還有一些地方,原本沒有為靜態(tài)生成考慮,另一些地方又需要兼容舊的設計.

           

          l         多臺前端Web

          這種結構要求生成的文件可能需要分布到多個服務器(另一個方案是放在幾臺專用的機器上,等前端來取)

           

          l         任務緊迫

          架構討論結束儀式六月初,離奧運開幕上線只有兩月,也就是說所有底層框架實現(xiàn),頁面模板開發(fā),調試測試,動作的整理,必須在7月底全部完成,按我原來估計,光實現(xiàn)這幾塊的上百個頁面模板和填充方法,也需要那么長的時間

           

          綜合考慮上述因素,架構必須要有以下幾個方面的特點

          l         動作可以靈活擴展配置,某個動作對應哪些生成,應該可以配置,并且可以分組

          l         文件必須有分發(fā)機制

          l         分發(fā)和生成必須獨立出來,并且支持分布式

          l         各種的動作,必須轉化為消息,發(fā)送到生成和分發(fā)服務器進行處理

          l         針對同意資源頻繁動作,在變量相同的情況下能夠具有合并的能力

          l         動作必須有記錄

          l         盡量考慮使用已有成熟技術,節(jié)省開發(fā)時間

          下面是設計的第一個架構

          用戶的動作經(jīng)過MSMQ[1]傳入到生成分發(fā)中心(途中綠色箭頭)進行處理,,處理中心接受到消息后,負責生成對應的頁面或者頁面區(qū)域,并將頁面分發(fā)到各個服務器,負載均衡沿用以前的架構,采用微軟的NLB[2]

           

          之所以用MSMQ,就是看上了他提供的完整的消息存儲恢復機制,這樣我們能確保即使服務器down掉重啟后,消息依然能正常處理,碰巧我們cms組的同事MSMQ非常熟悉,并且真準備在另外一個項目中使用類似的架構于是一拍即合

           

          頁面采用分塊存儲,這樣能保證生成時目標小,開銷小,也能重用性,然后再藉由SSI[3](shtml include)進行整合,之所以采取這樣的方案,而不采用Dottext的整合方式,是因為如果采用Dottext的方式,就必須走IIS.Net的管道[4],而據(jù)測試,經(jīng)過管道和直接返回html性能有非常大的差異,而使用ssi,在性能上是一個折中,并且可以Light HTTPd等高性能web服務器

           

          模板生成方式,采用了XSLT和另外一種自定義的模板(我的同事開發(fā)的機制,很有趣, 理論上能把傳統(tǒng)模板替換的性能開銷全部消除),生成的最終產(chǎn)物是shtml,之所以生成shtml是為了使用其ssi(Server Side Include)的特性,保證一定的靈活性,并實現(xiàn)熱點數(shù)據(jù)的分離:某些頁面上的部分可能會頻繁更新和生成,而其它地方不變,或者某個部分是所有頁面通用的(比如頁頭和頁腳),較之php下常常使用smarty,生成php文件,雖然靈活性不如php,但是性能上不相上下,還略高.

           

          但是這個設計的問題是動態(tài)內容和靜態(tài)內容沒有分開,生成的html頁面,和動態(tài)頁面都放在前端服務器上,通過負載均衡訪問,也造成了分發(fā)服務器需要分發(fā)到多臺服務器,網(wǎng)絡IO效率較低,而且靜態(tài)內容需要的磁盤空間很大,且小文件非常多,和動態(tài)頁面混在一起不便于優(yōu)化,所以第二個方案對生成的靜態(tài)內容與動態(tài)內容使用不同的服務器

           

          方案二:

          我們把生成的靜態(tài)文件單獨放置,可以看到,前端增加Nginx,作為跳轉,把電影,影人資料庫的頁面轉向靜態(tài)服務器,其他的調用轉向動態(tài)服務器,這樣我們就可以單獨為靜態(tài)服務器進行優(yōu)化,比如采用更高效的服務器等等.

           

          同時減少了文件分發(fā)的次數(shù)(甚至可以只分發(fā)到本機),提高生成分發(fā)的處理能力

           

          更進一步,可以把圖片服務分到另外一組機器上,使用獨立的域名,比如img.xxx.com,這樣可以有效的減少帶寬

           

          最終完整架構:

           

           

          文件生成分發(fā)中心

          下圖是文件生成分發(fā)中心的工作流程圖


          生成服務對外只有一個輸入,就是消息,一個輸出:靜態(tài)文件,內部根據(jù)消息,從配置文件中找到對應的生成方法,取出相應的模板,進行數(shù)據(jù)填充

           

          分發(fā)服務主要吧生成服務產(chǎn)生的文件進行分發(fā),分發(fā)到前端的N臺服務器上,開始考慮得比較復雜,希望分發(fā)服務可以跨越協(xié)議(本地文件系統(tǒng),局域網(wǎng),http協(xié)議),跨越多種存儲介質(文件系統(tǒng),數(shù)據(jù)庫),實際最后定下來基本是本地文件系統(tǒng)或者局域網(wǎng)傳輸

           

          :上圖中文件分發(fā)的部分也可以通過定制MogileFS,來實現(xiàn)分布式文件系統(tǒng)

           

          馬后炮:

          總結起來,靜態(tài)化除了對架構方面的影響,對開發(fā)和測試流程也有影響

          對測試提出更高的要求:

          因為一旦上線后,某個頁面發(fā)現(xiàn)問題,即使是文字的修改,也需要重新生成許多頁面,所以測試人員必須非常仔細,測試周期也需要延長

           

          開發(fā)人員需要掌握模板語言

          需要掌握一種模板預言,無論是Xslt還是自己開發(fā)的模板語言,都需要花一定的時間掌握

           

          需要給第一次生成騰出足夠時間:

          如果不是新系統(tǒng),那么數(shù)據(jù)遷移和生成的過程就比較痛苦,由于頁面眾多,第一次生成的過程可能需要以天來計算,在制定上線方案是就需要考慮到這個方面

           

          Nginx作為前端的跳轉,根據(jù)其他網(wǎng)站的經(jīng)驗,應該可以達到2-3萬并發(fā)連接,但是使用之后,常常有卡殼的情況發(fā)生,具體癥狀為在瀏覽器中訪問頁面時,連接超時,或者一直不響應,此時Nginx連接數(shù)并不高,好在還有第一套方案可以備用,讓我們有時間去解決這個問題,如果大家對這個問題有什么心得,歡迎交流

          posted on 2010-04-16 14:34 jinfeng_wang 閱讀(903) 評論(0)  編輯  收藏 所屬分類: ZZwebsite
          主站蜘蛛池模板: 仲巴县| 陆良县| 民乐县| 开化县| 县级市| 册亨县| 玉龙| 深水埗区| 都安| 屏边| 隆尧县| 宜春市| 上饶市| 突泉县| 山东| 乐业县| 吴江市| 尉犁县| 常宁市| 赤峰市| 四川省| 汉沽区| 汝城县| 乌鲁木齐县| 镇江市| 衡阳市| 中江县| 佛坪县| 绥棱县| 武汉市| 麻江县| 都江堰市| 濉溪县| 建德市| 衡山县| 夏津县| 修水县| 东阳市| 搜索| 拉萨市| 綦江县|