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

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

  我我的總結下來,這些大型動態網站之因此能夠作到能快速響應高併發,它們都是儘可能讓本身的網站靜態化,固然這種靜態化毫不是把網站就作成靜態網站,而是在充分理解了靜態網站在提高網站響應速度的基礎上對動態網站進行改良,因此我這裏首先要討論下靜態網站那些特色能夠用於咱們提高網站的響應速度。css

  靜態網站很是簡單,它就是經過一個url訪問web服務器上的一個網頁,web服務器接收到請求後在網絡上使用http協議將網頁返回給瀏覽器,瀏覽器經過解析http協議最終將頁面展現在瀏覽器裏,有時這個網頁會比較複雜點,裏面包含了一些額外的資源例如:圖片、外部的css文件、外部的js文件以及一些flash之類的多媒體資源,這些資源會單獨使用http協議把信息返回給瀏覽器,瀏覽器從頁面裏的src,href、Object這樣的標籤將這些資源和頁面組合在一塊兒,最終在瀏覽器裏展現頁面。可是無論什麼類型的資源,這些資源若是咱們不是手動的改變它們,那麼咱們每次請求得到結果都是同樣的。這就說明靜態網頁的一個特色:靜態網頁的資源基本是不會發生變化的。所以咱們第一次訪問一個靜態網頁和咱們之後訪問這個靜態網頁都是一個重複的請求,這種網站加載的速度基本都是由網絡傳輸的速度,以及每一個資源請求的大小所決定,既然訪問的資源基本不會發生變化,那麼咱們重複請求這些資源,本身在那裏空等不是很浪費時間嗎?如是乎,瀏覽器出現了緩存技術,咱們開發時候能夠對那些不變的資源在http協議上編寫相應指令,這些指令會讓瀏覽器第一次訪問到靜態資源後緩存起這些靜態資源,用戶第二次訪問這個網頁時候就再也不須要重複請求了,由於請求資源本地緩存,那麼獲取它的效率就變得異常高效。html

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

  網絡傳輸效率還和咱們傳輸資源的大小有關,所以咱們在資源傳輸前將其壓縮,減少資源的大小從而達到提高傳輸效率的目的;另外,每一個http請求其實都是一個tcp的請求,這些請求在創建鏈接和釋放鏈接都會消耗不少系統資源,這些性能的消耗時常會比傳輸內容自己還要大,所以咱們會盡力減小http請求的個數來達到提高傳輸效率的目的或者使用http長鏈接來消除創建鏈接和釋放鏈接的開銷(長鏈接的使用要看具體場景,這個我會在後面文章講到)。java

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

  我經常認爲最佳的性能優化手段就是使用緩存了,可是緩存的數據通常都是那些不會常常變化的數據,上文裏說到的瀏覽器緩存,CDN其實都是能夠當作緩存手段來理解,它們也是提高網站性能最爲有效的方式之一,可是這些緩存技術到了動態網站卻變得異常很差實施,這究竟是怎麼回事了?ajax

  首先動態網站和靜態網站有何不一樣呢?我以爲動態網站和靜態網站的區別就是動態網站網頁雖然也有一個url,可是咱們若是傳輸參數不一樣那麼這個url請求的頁面並非徹底同樣,也就是說動態網站網頁的內容根據條件不一樣是會發生改變的,可是這些變化的內容倒是同一個url,url在靜態網站裏就是一個資源的地址,那麼在動態網站裏一個地址指向的資源實際上是不一樣的。由於這種不一樣因此咱們無法把動態的網頁進行有效的緩存,並且不恰當的使用緩存還會引起錯誤,因此在動態網頁裏咱們會在meta設定頁面不會被瀏覽器緩存。算法

  若是每次訪問動態的網頁該網頁的內容都是徹底不一樣的,也許咱們就沒有必要寫網站靜態化的主題了,現實中的動態網頁每每只是其中一部分會發生變化,例如電商網站的菜單、頁面頭部、頁面尾部這些其實都不會常常發生變化,若是咱們只是由於網頁一小部分常常變化讓用戶每次請求都要重複訪問這些重複的資源,這實際上是很是消耗計算資源了,咱們來作個計算吧,假如一個動態頁面這些不變的內容有10k,該網頁一天有1000萬次的訪問量,那麼天天將消耗掉1億kb的網絡資源,這個其實很不划算的,並且這些重複消耗的寬帶資源並無爲網站的用戶體驗帶來好處,相反還拖慢了網頁加載的效率。那麼咱們就得考慮拆分網頁了,把網頁作一個動靜分離,讓靜態的部分當作不變的靜態資源進行處理,動態的內容仍是動態處理,而後在合適的地方將動靜內容合併在一塊兒。數據庫

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

  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

相關文章
相關標籤/搜索