關於大型網站技術演進的思考(九)--網站靜態化處理--總述(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架構了。

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


轉載自:http://www.cnblogs.com/sharpxiajun/p/4282789.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章