1. 程式人生 > >關於大型網站技術演進的思考(九)--網站靜態化處理--總述(1)

關於大型網站技術演進的思考(九)--網站靜態化處理--總述(1)

  在儲存瓶頸的開篇我提到像hao123這樣的導航網站只要它部署的web伺服器數量足夠,它可以承載超大規模的併發訪問量,如果是一個動態的網站,特別是使用到了資料庫的網站是很難做到通過增加web伺服器數量的方式來有效的增加網站併發訪問能力的。但是現實情況是像淘寶、京東這樣的大型動態網站在承擔高併發的情況下任然能保證快速的響應,這其中有什麼樣的技術手段可以達到動態網站支撐高併發的場景了,這也許是每個做web開發的朋友都很感興趣的問題,今天我將寫一個新的系列來探討下這個問題,希望我的經驗和研究能給大多數人以啟迪。這裡要說明下,本系列的寫法和儲存的瓶頸的寫法有所不同,本系列開始部分主要是講解原理,後面部分會針對原理講解具體的實現手段,如果有朋友感覺這種寫法不適應,還請諒解。

  我個人總結下來,這些大型動態網站之所以可以做到能快速響應高併發,它們都是儘量讓自己的網站靜態化,當然這種靜態化絕不是把網站就做成靜態網站,而是在充分理解了靜態網站在提升網站響應速度的基礎上對動態網站進行改良,所以我這裡首先要討論下靜態網站那些特點可以用於我們提升網站的響應速度。

  靜態網站非常簡單,它就是通過一個url訪問web伺服器上的一個網頁,web伺服器接收到請求後在網路上使用http協議將網頁返回給瀏覽器,瀏覽器通過解析http協議最終將頁面展示在瀏覽器裡,有時這個網頁會比較複雜點,裡面包含了一些額外的資源例如:圖片、外部的css檔案、外部的js檔案以及一些flash之類的多媒體資源,這些資源會單獨使用http協議把資訊返回給瀏覽器,瀏覽器從頁面裡的src,href、Object這樣的標籤將這些資源和頁面組合在一起,最終在瀏覽器裡展示頁面。但是不管什麼型別的資源,這些資源如果我們不是手動的改變它們,那麼我們每次請求獲得結果都是一樣的。這就說明靜態網頁的一個特點:靜態網頁的資源基本是不會發生變化的

。因此我們第一次訪問一個靜態網頁和我們以後訪問這個靜態網頁都是一個重複的請求,這種網站載入的速度基本都是由網路傳輸的速度,以及每個資源請求的大小所決定,既然訪問的資源基本不會發生變化,那麼我們重複請求這些資源,自己在那裡空等不是很浪費時間嗎?如是乎,瀏覽器出現了快取技術,我們開發時候可以對那些不變的資源在http協議上編寫相應指令,這些指令會讓瀏覽器第一次訪問到靜態資源後快取起這些靜態資源,使用者第二次訪問這個網頁時候就不再需要重複請求了,因為請求資源本地快取,那麼獲取它的效率就變得異常高效。

  由於靜態網站的請求資源是不會經常發生變化的,那麼這種資源其實很容易被遷移,我們都知道網路傳輸的效率是和距離長短有關係的,既然靜態資源很容易被遷移那麼我們就可以把靜態資源伺服器按地域分佈在多個服務節點上,當用戶請求網站時候根據一個路由演算法將請求落地在離使用者最近的節點上,這樣就可以減少網路傳輸的距離從而提升訪問的效率,這就是我們長提的大名鼎鼎的CDN技術,內容分發網路技術。

  網路傳輸效率還和我們傳輸資源的大小有關,因此我們在資源傳輸前將其壓縮,減小資源的大小從而達到提升傳輸效率的目的;另外,每個http請求其實都是一個tcp的請求,這些請求在建立連線和釋放連線都會消耗很多系統資源,這些效能的消耗時常會比傳輸內容本身還要大,因此我們會盡力減少http請求的個數來達到提升傳輸效率的目的或者使用http長連線來消除建立連線和釋放連線的開銷(長連線的使用要看具體場景,這個我會在後面文章講到)。

  其實雅虎提出的網站優化的14條建議大部分都是基於以上原理得出的,關於雅虎的14條件建議,本系列後面內容將做詳細的討論,這裡就不展開了。

  我常常認為最佳的效能優化手段就是使用快取了,但是快取的資料一般都是那些不會經常變化的資料,上文裡說到的瀏覽器快取,CDN其實都是可以當做快取手段來理解,它們也是提升網站效能最為有效的方式之一,但是這些快取技術到了動態網站卻變得異常不好實施,這到底是怎麼回事了?

  首先動態網站和靜態網站有何不同呢?我覺得動態網站和靜態網站的區別就是動態網站網頁雖然也有一個url,但是我們如果傳輸引數不同那麼這個url請求的頁面並不是完全一樣,也就是說動態網站網頁的內容根據條件不同是會發生改變的,但是這些變化的內容卻是同一個url,url在靜態網站裡就是一個資源的地址,那麼在動態網站裡一個地址指向的資源其實是不同的。因為這種不同所以我們沒法把動態的網頁進行有效的快取,而且不恰當的使用快取還會引發錯誤,所以在動態網頁裡我們會在meta設定頁面不會被瀏覽器快取。

  如果每次訪問動態的網頁該網頁的內容都是完全不同的,也許我們就沒有必要寫網站靜態化的主題了,現實中的動態網頁往往只是其中一部分會發生變化,例如電商網站的選單、頁面頭部、頁面尾部這些其實都不會經常發生變化,如果我們只是因為網頁一小部分經常變化讓使用者每次請求都要重複訪問這些重複的資源,這其實是非常消耗計算資源了,我們來做個計算吧,假如一個動態頁面這些不變的內容有10k,該網頁一天有1000萬次的訪問量,那麼每天將消耗掉1億kb的網路資源,這個其實很不划算的,而且這些重複消耗的寬頻資源並沒有為網站的使用者體驗帶來好處,相反還拖慢了網頁載入的效率。那麼我們就得考慮拆分網頁了,把網頁做一個動靜分離,讓靜態的部分當做不變的靜態資源進行處理,動態的內容還是動態處理,然後在合適的地方將動靜內容合併在一起。

  這裡有個關鍵點就是動靜合併的位置,這個位置的選擇會直接導致我們整個web前端的架構設計。我們這裡以java的web開發為例,來談談這個問題。

  java的web開發裡我們一般使用jsp來編寫頁面,當然也可以使用先進點的模板引擎開發頁面例如velocity,freemark等,不管我們頁面使用的是jsp還是模板引擎,這些類似html的檔案其實並不是真正的html,例如jsp本質其實是個servlet也就是一個java程式,所以它們的本質是服務端語言和html的一個整合技術,在實際執行中web容器會根據服務端的返回資料將jsp或模板引擎解析成瀏覽器能解析的html,然後傳輸這個html到瀏覽器進行解析。由此可見服務端語言提供的開發頁面的技術其實是動靜無法分離的源頭,但是這些技術可以很好的完成動靜資源中的動的內容,因此我們想做動靜分離那麼首先就要把靜的資源從jsp或者模板語言裡抽取出來,抽取出來的靜態資源當然就要交給靜態的web伺服器來處理,我們常用的靜態資源伺服器一般是apache或ngnix,所以這些靜態資源應該放置在這樣的伺服器上,那麼我們是否可以在這些靜態web伺服器上做動靜結合呢?答案是還真行,例如apache伺服器有個模組就可以將它自身儲存的靜態資源和服務端傳輸的資源整合在一起,這種技術叫做ESI,這個時候我們可以把不變的靜態內容製作成模板放置在靜態伺服器上,動態內容達到靜態資源伺服器時候,使用ESI或者CSI的標籤,把動靜內容結合在一起,這就完成了一個動靜結合操作。這裡就有一個問題了,我前面提到過CDN,CDN其實也是一組靜態的web伺服器,那麼我們是否可以把這些事情放到CDN做了?理論上是可以做到,但是現實卻是不太好做,因為除了一些超有錢的網際網路公司,大部分公司使用的CDN都是第三方提供的,第三方的CDN往往是一個通用方案,再加上人家畢竟不是自己人,而且CDN的主要目的也不是為了做動靜分離,因此大部分情況下在CDN上完成這類操作並不是那麼順利,因此我們常常會在服務端的web容器前加上一個靜態web伺服器,這個靜態伺服器起到一個反向代理的作用,它可以做很多事情,其中一件事情就是可以完成這個動靜結合的問題。

  那麼我們把這個動靜結合點再往前推,推到瀏覽器,瀏覽器能做到這件事情嗎?如果瀏覽器可以,那麼靜態資源也就可以快取在客戶端了,這比快取在CDN效率還要高,其實瀏覽器還真的可以做到這點,特別是ajax技術出現後,瀏覽器來整合這個動靜資源也就變得更加容易了。不過一般而言,我們使用ajax做動靜分離都是都是從服務端請求一個html片段,到了瀏覽器後,使用dom技術將這個片段整合到頁面裡,雖然這個已經比全頁面返回高效很多,但是他還是有問題的,服務端處理完請求最終返回結果其實都是很純粹的資料,可是這些資料我們不得不轉化為頁面片段返回給瀏覽器,這本質是為純粹的資料上加入了很多與服務端無用的結構,之所以說無用是因為瀏覽器自身也可以完成這些結構,為什麼我們一定要讓服務端做這個事情了?如是乎javascript的模板技術出現了,這些模板技術和jsp,velocity類似,只不過它們是通過javascript設計的模板語言,有了javascript模板語言,服務端可以完全不用考慮對頁面的處理,它只需要將有效的資料返回到頁面就行了,使用了javascript模板技術,可以讓我們動靜資源分離做的更加徹底,基本上所有的瀏覽器相關的東西都被靜態化了,服務端只需要把最原始的資料傳輸到瀏覽器即可。講到這裡我們就說到了web前端最前沿的技術了:javascriptMVC架構了。

  好了今天就寫到這裡,本篇文章是網站靜態化處理理論的總述,後面的文章我將會一點一滴的講述實現網站靜態化的各種技術實現細節。

相關推薦

關於大型網站技術演進思考--網站靜態處理--1

  在儲存瓶頸的開篇我提到像hao123這樣的導航網站只要它部署的web伺服器數量足夠,它可以承載超大規模的併發訪問量,如果是一個動態的網站,特別是使用到了資料庫的網站是很難做到通過增加web伺服器數量的方式來有效的增加網站併發訪問能力的。但是現實情況是像淘寶、京東這樣的大型動態網站在承擔高併發的情況下任然能

關於大型網站技術演進思考十八--網站靜態處理—反向代理10

  反向代理也是一種可以幫助實現網站靜態化的重要技術,今天我就來講講反向代理這個主題。那麼首先我們要了解下什麼是反向代理。和反向代理相對應的是正向代理,正向代理也就是我們常說的代理服務,正向代理是非常常見的,例如在某些公司裡我們想使用網際網路,那麼我們就得在瀏覽器裡設定一個代理伺服器,通過代理伺服器我們才能正

關於大型網站技術演進思考--網站靜態處理—web前端優化—上11

對於一個網路請求的處理,是由兩個不同型別的操作共同完成,這兩個操作是CPU的計算操作和IO操作,如果我們以處理效率角度來評判這兩個操作,CPU操作效率是光速的,而IO操作就不盡然了,計算機裡的IO操作就是對儲存資料介質的操作,計算機裡有如下幾個介質可以儲存資料,它們分別是:CPU的一級快取、二級快取、記憶

關於大型網站技術演進思考--存儲的瓶頸5

做了 技術分享 表數 例子 執行 同時 設備 系統重啟 拆分 原引:http://www.cnblogs.com/sharpxiajun/p/4265853.html 上文裏我遺留了兩個問題,一個問題是數據庫做了水平拆分以後,如果我們對主鍵的設計采取一種均勻分布的策略,那麽

關於大型網站技術演進思考十四--網站靜態處理—前後端分離—上6

  前文講到了CSI技術,這就說明網站靜態化技術的講述已經推進到了瀏覽器端了即真正到了web前端的範疇了,而時下web前端技術的前沿之一就是前後端分離技術了,那麼在這裡網站靜態化技術和前後端分離技術產生了交集,所以今天我將討論下前後端分離技術,前後端分離技術討論完後,下一篇文章我將會以網站靜態化技術的角度回過

關於大型網站技術演進思考--網站靜態處理—動靜整合方案2

  上篇文章我簡要的介紹了下網站靜態化的演進過程,有朋友可能認為這些知識有點過於稀鬆平常了,而且網站靜態化的技術基點也不是那麼高深和難以理解,因此它和時下日新月異的web前端技術相比,就顯得不倫不類了。其實當我打算寫本系列的之前我個人覺得web前端有一個點是很多人都知道重要,但是有常常低估它作用的,那就是we

關於大型網站技術演進思考--儲存的瓶頸2

  上篇裡我講到某些網站在高併發下會報出503錯誤,503錯誤的含義是指網站服務端暫時無法提供服務的含義,503還表達了網站服務端現在有問題但是以後可能會提供正常的服務,對http協議熟悉的人都知道,5開頭的響應碼錶達了服務端出現了問題,在我們開發測試時候最為常見的是500錯誤,500代表的含義是服務端程式出

關於大型網站技術演進思考十五--網站靜態處理—前後端分離—中7

  上篇裡我講到了一種前後端分離方案,這套方案放到服務端開發人員面前比放在web前端開發人員面前或許得到的掌聲會更多,我想很多資深前端工程師看到這樣的技術方案可能會有種說不出來的矛盾心情,當我的工作逐漸走向越來越專業化的前端開發後,我就時常被這套前後端分離方案所困惑,最近我終於明白了這個困惑的本源在哪裡了,那

關於大型網站技術演進思考十七--網站靜態處理—滿足靜態的前後端分離9

  前後端分離的主題雖然講完了,但是前後端分離的內容並沒有結束,本篇將繼續前後端分離的問題,只不過這次前後端分離的講述將會圍繞著本系列的主題網站靜態化進行。在講本篇主題之前,我需要糾正一下前後端分離主題講述中會讓朋友們產生誤導的地方,這種誤導就是對時下流行的一些前後端分離方案(沒有使用nodejs的前後端分離

關於大型網站技術演進思考--儲存的瓶頸6

  在講資料庫水平拆分時候,我列出了水平拆分資料庫需要解決的兩個難題,它們分別是主鍵的設計問題和單表查詢的問題,主鍵問題前文已經做了比較詳細的講述了,但是第二個問題我沒有講述,今天我將會講講如何解決資料表被水平拆分後的單表查詢問題。   要解決資料表被水平拆分後的單表查詢問題,我們首先要回到問題的源頭,我們

關於大型網站技術演進思考十六--網站靜態處理—前後端分離—下8

  我第一次聽說nodejs技術大概是在2009年年末,不過我真正認真在網路上進一步瞭解nodejs還是在2010年年中,當時對nodejs的認識和我現在對nodejs的認識有著天壤的區別,開始想了解nodejs我只是為了感慨谷歌公司開發的V8引擎居然如此強大,它不僅僅可以作為chrome瀏覽器的javasc

關於大型網站技術演進思考十一--網站靜態處理—動靜分離策略3

  前文裡我講到了網站靜態化的關鍵點是動靜分離,動靜分離是讓動態網站裡的動態網頁根據一定規則把不變的資源和經常變的資源區分開來,動靜資源做好了拆分以後,我們就可以根據靜態資源的特點將其做快取操作,這就是網站靜態化處理的核心思路。由此可見,網站靜態化處理的核心就是動靜分離和快取兩大方面,上篇我簡單講述了動靜整合

關於大型網站技術演進思考--儲存的瓶頸1

  前不久公司請來了位網際網路界的技術大牛跟我們做了一次大型網站架構的培訓,兩天12個小時資訊量非常大,知識的廣度和難度也非常大,培訓完後我很難完整理出全部聽到的知識,今天我換了個思路是回味這次培訓,這個思路就是通過本人目前的經驗和技術水平來思考下大型網站技術演進的過程。   首先我們要思考一個問題,什麼樣

關於大型網站技術演進思考--儲存的瓶頸4

  如果資料庫需要進行水平拆分,這其實是一件很開心的事情,因為它代表公司的業務正在迅猛的增長,對於開發人員而言那就是有不盡的專案可以做,雖然會感覺很忙,但是人過的充實,心裡也踏實。   資料庫水平拆分簡單說來就是先將原資料庫裡的一張表在做垂直拆分出來放置在單獨的資料庫和單獨的表裡後更進一步的把本來是一個整體

關於大型網站技術演進思考--儲存的瓶頸7

  本文開篇提個問題給大家,關係資料庫的瓶頸有哪些?我想有些朋友看到這個問題肯定會說出自己平時開發中碰到了一個跟資料庫有關的什麼什麼問題,然後如何解決的等等,這樣的答案沒問題,但是卻沒有代表性,如果出現了一個新的儲存瓶頸問題,你在那個場景的處理經驗可以套用在這個新問題上嗎?這個真的很難說。   其實不管什麼

關於大型網站技術演進思考--儲存的瓶頸5

  上文裡我遺留了兩個問題,一個問題是資料庫做了水平拆分以後,如果我們對主鍵的設計採取一種均勻分佈的策略,那麼它對於被水平拆分出的表後續的查詢操作將有何種影響,第二個問題就是水平拆分的擴容問題。這兩個問題在深入下去,本系列就越來越技術化了,可能最終很多朋友讀完後還是沒有找到解決實際問題的啟迪,而且我覺得這些問

關於大型網站技術演進思考--儲存的瓶頸3

  儲存的瓶頸寫到現在就要進入到深水區了,如果我們所做的網站已經到了做資料庫垂直拆分和水平拆分的階段,那麼此時我們所面臨的技術難度的挑戰也會大大增強。   這裡我們先回顧下資料庫的垂直拆分和水平拆分的定義:   垂直拆分:把一個數據庫中不同業務單元的資料分到不同的資料庫裡。   水平拆分:是根據一定的規

關於大型網站技術演進思考十三--網站靜態處理—CSI5

  講完了SSI,ESI,下面就要講講CSI了 ,CSI是瀏覽器端的動靜整合方案,當我文章發表後有朋友就問我,CSI技術是不是就是通過ajax來載入資料啊,我當時的回答只是說你的理解有點片面,那麼到底什麼是CSI技術了?這個其實要和動靜資源整合的角度來定義。   CSI技術其實是在頁面進行動靜分離後,將頁面

關於大型網站技術演進思考十二--網站靜態處理—快取4

  上篇我補充了下SSI的知識,SSI是一個十分常見的技術,記得多年前我看到很多入口網站頁面的字尾是.shtml,那麼這就說明很多入口網站都曾經使用過SSI技術,其實現在搜狐網站也還在用shtml,如下圖所示:     由此可見SSI在網際網路的應用還是非常廣泛的。其實網際網路很多網頁如果我們按照動靜分離

關於大型網站技術演進思考--儲存的瓶頸終篇8

  在開始本篇主要內容前,我們一起看看下面的幾張截圖,首先是第一張圖,如下圖所示:     這是一家電商網站的首頁,當我們第一次開啟這個首頁,網站會彈出一個強制性的對話方塊,讓使用者選擇貨物配送的地址,如果是淘寶和京東的話,那麼這個選擇配貨地址的選項是在商品裡,如下圖是淘寶的選擇配送地點:     下