天天看點

談談網站靜态化

談談網站靜态化 收藏 寫在前頭 靜态化是解決減輕網站壓力,提高網站通路速度的常用方案,但在強調互動的We2.0 時代,對靜态化提出了更高的要求,靜态不僅要能靜,還要能動,下面我通過一個項目,談談網站靜态化後的架構設計方案,同時和大家探讨一下,在開源産品大行其道,言架構必稱MemberCache, Nginx,的時代,微軟技術在網站架構設計中的運用. 靜态化的設計原則和步驟 靜态化是解決減輕網站壓力,但是靜态化也會帶來一系列的問題,包括開發上複雜度的增加,維護難度的增加,運用不的當,更可能适得其反,而許多替代方案,比如頁面緩存,如果運用得當,也能起到很好的效果,是以在開始之前,必須進行詳細的考察,确定是否适合靜态化,并制定适合的靜态化方式,下面先介紹一下 l 考查讀寫比: 讀寫比,準确的說是讀寫負荷比,是否值得靜态化的最終考慮,由于一般寫入的壓力明顯大于讀出的壓力,如果寫入太頻繁,或者每次寫入消耗的資源太多,都不能達到效果,我覺得讀寫比例10:1應該是個上限.具體情況需要根據自己的業務邏輯判斷 l 确定頁面呈現的内容是否适合靜态化: 在設計方案時,必須詳細考慮每個原型頁面,找到頁面上展示的資訊,和他的更新方式,更新時機,更新頻率,一定要注意那些不起眼的資訊,他們可能左右你的設計, 比如:我們以CSDN的論壇的任意一篇文章為例,進行分析 上面的文章中呈現的内容主要是這樣幾塊,文章内容,回複内容,發帖人回複人的使用者資訊 n 文章内容和回複内容在發帖時更新,發帖後使用者可以修改其内容,更新頻率高 n 使用者資訊,使用者修改個人資訊時可能會發生更改,使用者等級增加時也可能發生更改,比如加星,更新頻率低 n 回複數将每次回複後都要更改,更新頻率高 n 設計時要注意細節,如上圖中圈出來的部分,這些部分是怎麼修改的,頻率有多大,一個都不能放過. l 确定生成方式: 在上面文章一例中.每次更改都重新生成頁面是不可取的,一篇比回複數多的文章,需要的資料量是巨大的(每層樓的使用者資訊,回複内容),任何修改,都需要重新取出資料進行生成是不能允許的.一般除非你的頁面基本不用更新,或者更新開銷極小,(比如一段嵌入的廣告代碼)才能采用整體更新的方式,不然就需要我們找到合适的更新頁面局部區域的方法: 一般有下面兩個方法: 1) 正則修改法: 比如,如果文章中的回複數,html代碼是這樣 回複數34 我們可以通過用下面正則來查找并替換計數 (?<=>)/d{1,} 2) 頁面區域分塊: 把頁面分成很多小塊,在顯示時組裝起來,比如DotText就采用這個方法 這是一篇典型的Dottext blog頁面,其中紅色标定部分是一個獨立的檔案,而黃色框内的是腳本動态加載,這些部分在最終顯示的時候組合起來,最終構成了一篇Blog,具體的組合方法也有多種,可以使用Include,也可以自己來實作.DotText就自己實作了一套加載機制 上面的兩種方法并不孤立,并可以根據需要,配合使用 l 确定需要動态加載的資訊: 頁面上總有一些内容看起來不太适合靜态化,最典型的是一些統計結果,比如如果你在做一個圖書介紹頁面,可能就會需要展示圖書的當天綜合評分,或者書籍排名,這些内容需要用腳本進行動态加載 既然做了靜态化,就是希望減少伺服器負載,動态加載的資料總是不得已而為之,有的時候在需求允許的情況下,我們在資料在實時性和性能方面做一些妥協,比如上面文章中的使用者星級和昵稱,從資料實時性上說,當使用者的星級增長,他發言的所有文章都應該發生變化,是以應該用動态加載.然而其實上這些資訊如果不發生變化,也無傷大雅,使用者反而能夠看到自己在多年前發帖時的級别和昵稱. 現實中的項目 X網站是大型的電影資訊,電影社群,向外提供電影相關資訊服務,以及使用者社群,其中資訊服務部分, 其中大部分頁面屬于資訊呈現頁,讀取量比較大,百萬級别pv,資訊主要由編輯在背景釋出,更新較少,但其頁面上有大量的互動性的内容,比如評論,收藏清單,同時許多内容允許使用者創造,比如上傳圖檔,添加注釋.互動内容的數量和互動的頻繁程度,都超過了普通的咨詢頁面,這次調整,準備将其中通路量最大的幾塊:電影資料頁,影人資料頁,進行靜态化,如果成功,還将運用到更多的頻道,基本實作全站靜态化 通過對頁面設計和前一版本的分析,下面是具有挑戰性的地方.這些特點基本使用于大多數web2.0的站點,很具有典型意義 l 頁面生成的觸發條件複雜 一般論壇中的文章或者blog,更新方式比較單一:主要是由回複進行觸發還有少數的修改動作,然而該網站一個頁面上需要根據不同觸發條件就有20多個, 比如光二級菜單:使用者釋出圖檔,删除圖檔,釋出或者删除影片資訊,釋出或者修改視訊,背景修改電影資訊,都有可能觸發 l 一個動作觸發生成的頁面可能很多而且互相交疊 每一個動作都會觸發一系列的生成,并且不同動作可能都會涉及同一個頁面或者區域的生成. 比如:使用者給一步電影評分,需要生成評分更多頁,評分統計更多頁,首頁右側誰還關注此影片小區域,等等.使用者收藏一個影片,也需要更新首頁右側誰還關注此影片小區域 l 觸發頻繁: 雖然不及某些更大規模的網站,但是由于涉及衆多使用者參與的内容,評論,收藏等等,觸發點多,發生頻度相當頻繁 l 頁面多,結構複雜,空間占用大: 通常,需要生成的頁面規模是這樣粗略估算的,Rn*P,Rn為資源數,P為每個資源的頁面數,所謂資源,可以看做一個生成機關,其頁面數可以簡單看做釋出一個資源,就需要生成其所有相關頁面數量,比如:釋出一個blog,就需要生成一個Blog頁,同時還需要生成或者更新個人首頁的blog清單,算上個人首頁右側的分類文章數的小塊,也就是最多10來個頁面或者區域,但是釋出一個電影,其相關的頁面至少有50個以上,而且有的頁面還帶有分頁,一個資訊比較豐富的電影,其頁面竟可以達到千個以上,空間10~20M,而且資源總數也不少,電影80000左右,電影人雖然P值較少,但是總量确有幾十萬之巨,估計靜态頁面磁盤占用量幾百個G l 向下相容 這是一個已有系統,舊系統的框框需要突破,但又沒有時間,或者不能完全突破,比如Url,已經被收錄到搜尋引擎,就不能随便調整,還有一些地方,原本沒有為靜态生成考慮,另一些地方又需要相容舊的設計. l 多台前端Web 這種結構要求生成的檔案可能需要分布到多個伺服器(另一個方案是放在幾台專用的機器上,等前端來取) l 任務緊迫 架構讨論結束儀式六月初,離奧運開幕上線隻有兩月,也就是說所有底層架構實作,頁面模闆開發,調試測試,動作的整理,必須在7月底全部完成,按我原來估計,光實作這幾塊的上百個頁面模闆和填充方法,也需要那麼長的時間 綜合考慮上述因素,架構必須要有以下幾個方面的特點 l 動作可以靈活擴充配置,某個動作對應哪些生成,應該可以配置,并且可以分組 l 檔案必須有分發機制 l 分發和生成必須獨立出來,并且支援分布式 l 各種的動作,必須轉化為消息,發送到生成和分發伺服器進行處理 l 針對同意資源頻繁動作,在變量相同的情況下能夠具有合并的能力 l 動作必須有記錄 l 盡量考慮使用已有成熟技術,節省開發時間 下面是設計的第一個架構 使用者的動作經過MSMQ[1]傳入到生成分發中心(途中綠色箭頭)進行處理,,進行中心接受到消息後,負責生成對應的頁面或者頁面區域,并将頁面分發到各個伺服器,負載均衡沿用以前的架構,采用微軟的NLB[2] 之是以用MSMQ,就是看上了他提供的完整的消息存儲恢複機制,這樣我們能確定即使伺服器down掉重新開機後,消息依然能正常處理,碰巧我們cms組的同僚MSMQ非常熟悉,并且真準備在另外一個項目中使用類似的架構—于是一拍即合 頁面采用分塊存儲,這樣能保證生成時目标小,開銷小,也能重用性,然後再藉由SSI[3](shtml include)進行整合,之是以采取這樣的方案,而不采用Dottext的整合方式,是因為如果采用Dottext的方式,就必須走IIS和.Net的管道[4],而據測試,經過管道和直接傳回html性能有非常大的差異,而使用ssi,在性能上是一個折中,并且可以Light HTTPd等高性能web伺服器 模闆生成方式,采用了XSLT和另外一種自定義的模闆(我的同僚開發的機制,很有趣, 理論上能把傳統模闆替換的性能開銷全部消除),生成的最終産物是shtml,之是以生成shtml是為了使用其ssi(Server Side Include)的特性,保證一定的靈活性,并實作熱點資料的分離:某些頁面上的部分可能會頻繁更新和生成,而其它地方不變,或者某個部分是所有頁面通用的(比如頁頭和頁腳),較之php下常常使用smarty,生成php檔案,雖然靈活性不如php,但是性能上不相上下,還略高. 但是這個設計的問題是動态内容和靜态内容沒有分開,生成的html頁面,和動态頁面都放在前端伺服器上,通過負載均衡通路,也造成了分發伺服器需要分發到多台伺服器,網絡IO效率較低,而且靜态内容需要的磁盤空間很大,且小檔案非常多,和動态頁面混在一起不便于優化,是以第二個方案對生成的靜态内容與動态内容使用不同的伺服器 方案二: 我們把生成的靜态檔案單獨放置,可以看到,前端增加Nginx,作為跳轉,把電影,影人資料庫的頁面轉向靜态伺服器,其他的調用轉向動态伺服器,這樣我們就可以單獨為靜态伺服器進行優化,比如采用更高效的伺服器等等. 同時減少了檔案分發的次數(甚至可以隻分發到本機),提高生成分發的處理能力 更進一步,可以把圖檔服務分到另外一組機器上,使用獨立的域名,比如img.xxx.com,這樣可以有效的減少帶寬 最終完整架構: 檔案生成分發中心 下圖是檔案生成分發中心的工作流程圖 生成服務對外隻有一個輸入,就是消息,一個輸出:靜态檔案,内部根據消息,從配置檔案中找到對應的生成方法,取出相應的模闆,進行資料填充 分發服務主要吧生成服務産生的檔案進行分發,分發到前端的N台伺服器上,開始考慮得比較複雜,希望分發服務可以跨越協定(本地檔案系統,區域網路,http協定),跨越多種存儲媒體(檔案系統,資料庫),實際最後定下來基本是本地檔案系統或者區域網路傳輸 注:上圖中檔案分發的部分也可以通過定制MogileFS,來實作分布式檔案系統 馬後炮: 總結起來,靜态化除了對架構方面的影響,對開發和測試流程也有影響 對測試提出更高的要求: 因為一旦上線後,某個頁面發現問題,即使是文字的修改,也需要重新生成許多頁面,是以測試人員必須非常仔細,測試周期也需要延長 開發人員需要掌握模闆語言 需要掌握一種模闆預言,無論是Xslt還是自己開發的模闆語言,都需要花一定的時間掌握 需要給第一次生成騰出足夠時間: 如果不是新系統,那麼資料遷移和生成的過程就比較痛苦,由于頁面衆多,第一次生成的過程可能需要以天來計算,在制定上線方案是就需要考慮到這個方面 Nginx作為前端的跳轉,根據其他網站的經驗,應該可以達到2-3萬并發連接配接,但是使用之後,常常有卡殼的情況發生,具體症狀為在浏覽器中通路頁面時,連接配接逾時,或者一直不響應,此時Nginx連接配接數并不高,好在還有第一套方案可以備用,讓我們有時間去解決這個問題,如果大家對這個問題有什麼心得,歡迎交流 我的聯系方式 MSN:[email protected] Gtalk:[email protected] 篇後: 在大型web開發上,我感到微軟産品結構(包括微軟開源社群的成果)在某些方面還存在一些不足: 高性能伺服器選擇太少 Linux下可以采用Light HTTPd,Nginx等諸多伺服器,這些伺服器在很多方面的表現會讓Windows下唯一的選擇--IIS相形見绌 分布式檔案系統 微軟及其社群沒有比較著名的産品出現,Linux下有MogileFS 微軟架構下,檔案系統選擇太少: 在Linux下我們可以選擇諸如Ext3,ReiserFS,而Windows環境下,NTFS是唯一的選擇,不過值得稱道的是.NTFS的效率和穩定性都相當不錯. 開源技術對windows版本的支援态度不積極 諸多在Linux下名聲卓著的開源産品,又懶于為Windows提供相應的版本,或者提供的windows版本效果差強人意.使得采用微軟伺服器的廠商少了很多選擇 現在的Web開發已經進入了各種技術大混合,大整合的時代,任何一個廠商都不可能涵蓋所有方面,在後端架構和邏輯方面.Net和Java嚴謹,良好的程式設計風格,清晰的設計思路,較高的運作效率,以及穩定的配套服務支援,是其最大的優勢,對主要擅長微軟技術的Web工程師和架構師而言,應該增進對Linux及開源社群的了解,才能根據需求設計出合理的架構 [1] Message Queuing: A Scalable, Highly Available Load-Balancing Solution http://msdn.microsoft.com/en-us/library/ms811052.aspx [2] 網絡負載平衡(NLB)詳解,注意文章後給出的參考連結 http://blog.chinaitlab.com/user1/563173/archives/2007/132713.html [3] 怎樣使用ssi,及其文法: Nginx下的ssimodule http://www.nginx.cn/NginxChsHttpSsiModule [4] asp.net的處理機制http://www.microsoft.com/china/msdn/library/webservices/asp.net/dnvs05Internals.mspx?mfr=true html.asp.aspx運作效率比較 http://iamlibai.blogbus.com/logs/2017870.html

繼續閱讀