如何讓你的網站提速:Web緩存加速指南(一)

這是一篇知識性的文檔,主要目的是爲了讓Web緩存相關概念更容易被開發者理解並應用於實際的應用環境中。爲了簡要起見,某些實現方面的細節被簡化或省略了。若是你更關心細節實現則徹底沒必要耐心看完本文,後面參考文檔和更多深刻閱讀部分多是你更須要的內容。html

  什麼是Web緩存,爲何要使用它?web

 http://blog.csdn.net/shoyer/article/details/8457952數據庫

  緩存的類型:瀏覽器

  瀏覽器緩存;緩存

 

  代理服務器緩存;安全

 

  Web緩存無害嗎?爲何要鼓勵緩存?服務器

 

  Web緩存如何工做:cookie

  如何控制(控制不)緩存:網絡

  HTML Meta標籤 vs. HTTP頭信息;負載均衡

 

  Pragma HTTP頭信息(爲何不起做用);

 

  使用Expires(過時時間)HTTP頭信息控制保鮮期;

  Cache-Control(緩存控制) HTTP頭信息;

 

  校驗參數和校驗;

  建立利於緩存網站的竅門;

 

  編寫利於緩存的腳本;

 

  常見問題解答;

  緩存機制的實現:Web服務器端配置;

  緩存機制的實現:服務器端腳本;

  參考文檔和深刻閱讀;

  關於本文檔;

 

  什麼是Web緩存,爲何要使用它?

 

  Web緩存位於Web服務器之間(1個或多個,內容源服務器)和客戶端之間(1個或多個):緩存會根據進來的請求保存輸出內容的副本,例如html頁面, 圖片,文件(統稱爲副本),而後,當下一個請求來到的時候:若是是相同的URL,緩存直接使用副本響應訪問請求,而不是向源服務器再次發送請求。

 

  使用緩存主要有2大理由:

 

  減小相應延遲:由於請求從緩存服務器(離客戶端更近)而不是源服務器被相應,這個過程耗時更少,讓web服務器看上去相應更快;

 

  減小網絡帶寬消耗:當副本被重用時會減低客戶端的帶寬消耗;客戶能夠節省帶寬費用,控制帶寬的需求的增加並更易於管理。

 

  緩存的類型

  瀏覽器緩存

  對於新一代的Web瀏覽器來講(例如:IE,Firefox):通常都能在設置對話框中發現關於緩存的設置,經過在你的電腦上僻處一塊硬盤空間用於存儲你已經看過的網站的副本。瀏覽器緩存根據很是簡單的規則進行工做:在同一個會話過程當中(在當前瀏覽器沒有被關閉以前)會檢查一次並肯定緩存的副本足夠新。這個緩存對於用戶點擊「後退」或者點擊剛訪問過的連接特別有用,若是你瀏覽過程當中訪問到同一個圖片,這些圖片能夠從瀏覽器緩存中調出而即時顯現。

  代理服務器緩存

 

  Web代理服務器使用一樣的緩存原理,只是規模更大。代理服務器羣爲成百上千用戶服務使用一樣的機制;大公司和ISP常常在他們的防火牆上架設代理緩存或者單獨的緩存設備;

  因爲帶路服務器緩存並不是客戶端或者源服務器的一部分,而是位於原網絡以外,請求必須路由到他們才能起做用。一個方法是手工設置你的瀏覽器:告訴瀏覽器使用 那個代理,另一個是經過中間服務器:這個中間服務器處理全部的web請求,並將請求轉發到後臺網絡,而用戶沒必要配置代理,甚至沒必要知道代理的存在;

 

  代理服務器緩存:是一個共享緩存,不僅爲一個用戶服務,常常爲大量用戶使用,所以在減小相應時間和帶寬使用方面頗有效:由於同一個副本會被重用屢次。

 

  網關緩存

  也被稱爲反向代理緩存或間接代理緩存,網關緩存也是一箇中間服務器,和內網管理員部署緩存用於節省帶寬不一樣:網關緩存通常是網站管理員本身部署:讓他們的網站更容易擴展並得到更好的性能;

 

  請求有幾種方法被路由到網關緩存服務器上:其中典型的是讓用一臺或多臺負載均衡服務器從客戶端看上去是源服務器;

 

  網絡內容發佈商 (Content delivery networks CDNs)分佈網關緩存到整個(或部分)互聯網上,並出售緩存服務給須要的網站,Speedera和Akamai就是典型的網絡內容發佈商(下文簡稱CDN)。

  本問主要關注於瀏覽器和代理緩存,固然,有些信息對於網關緩存也一樣有效;

 

  Web緩存無害嗎?爲何要鼓勵緩存?

  Web緩存在互聯網上最容易被誤解的技術之一:網站管理員常常怕對網站失去控制,因爲代理緩存會「隱藏」他們的用戶,讓他們感受難以監控誰在使用他們的網站。

  不幸的是:就算不考慮Web緩存,互聯網上也有不少網站使用很是多的參數以便管理員精確地跟蹤用戶如何使用他們的網站;若是這類問題也是你關心的,本文將告訴你如何得到精確的統計而沒必要將網站設計的很是緩存不友好。

 

  另一個抱怨是緩存會給用戶過時或失效的數據;不管如何:本文能夠告訴你怎樣配置你的服務器來控制你的內容將被如何緩存。

 

  CDN是另一個有趣的方向,和其餘代理緩存不一樣:CDN的網關緩存爲但願被緩存的網站服務,沒有以上顧慮。即便你使用了CDN,你也要考慮後續的代理服務器緩存和瀏覽器緩存問題。

  另一方面:若是良好地規劃了你的網站,緩存會有助於網站服務更快,並節省服務器負載和互聯網的連接請求。這個改善是顯著的:一個難以緩存的網站可能須要幾秒去載入頁面,而對比有緩存的網站頁面幾乎是即時顯現:用戶更喜歡速度快的網站並更常常的訪問;

  這樣想:不少大型互聯網公司爲全世界服務器羣投入上百萬資金,爲的就是讓用戶訪問儘量快,客戶端緩存也是這個目的,只不過更靠近用戶一端,並且最好的一點是你甚至根本不用爲此付費。

  事實上,不管你是否喜歡,代理服務器和瀏覽器都回啓用緩存。若是你沒有配置網站正確的緩存,他們會按照缺省或者緩存管理員的策略進行緩存。

 

  緩存如何工做

 

  全部的緩存都用一套規則來幫助他們決定何時使用緩存中的副本提供服務(假設有副本可用的狀況下);一些規則在協議中有定義(HTTP協議1.0和1.1),一些規則由緩存的管理員設置(瀏覽器的用戶或者代理服務器的管理員);

  通常說來:遵循如下基本的規則(沒必要擔憂,你沒必要知道全部的細節,細節將隨後說明)

 

  若是響應頭信息:告訴緩存器不要保留緩存,緩存器就不會緩存相應內容;

  若是請求信息是須要認證或者安全加密的,相應內容也不會被緩存;

 

若是在迴應中不存在校驗器(ETag或者Last-Modified頭信息),緩存服務器會認爲缺少直接的更新度信息,內容將會被認爲不可緩存。

 

  一個緩存的副本若是含有如下信息:內容將會被認爲是足夠新的

 

  含有完整的過時時間和壽命控制頭信息,而且內容仍在保鮮期內;

 

  瀏覽器已經使用過緩存副本,而且在一個會話中已經檢查過內容的新鮮度;

 

  緩存代理服務器近期內已經使用過緩存副本,而且內容的最後更新時間在上次使用期以前;

 

  夠新的副本將直接從緩存中送出,而不會向源服務器發送請求;

 

  若是緩存的副本已經太舊了,緩存服務器將向源服務器發出請求校驗請求,用於肯定是否能夠繼續使用當前拷貝繼續服務;

  總之:新鮮度和校驗是肯定內容是否可用的最重要途徑:

 

  若是副本足夠新,從緩存中提取就馬上能用了;

  而經緩存器校驗後發現副本的原件沒有變化,系統也會避免將副本內容從源服務器整個從新傳輸一遍。

 

  如何控制(控制不)緩存

  有不少工具能夠幫助設計師和網站管理員調整緩存服務器對待網站的方式,這也許須要你親自下手對服務器的配置進行一些調整,但絕對值得;瞭解如何使用這些工具請參考後面的實現章節;

 

  HTML meta標籤和HTTP 頭信息

 

  HTML的編寫者會在文檔的區域中加入描述文檔的各類屬性,這些META標籤經常被用於標記文檔不能夠被緩存或者標記多長時間後過時;

 

  META標籤使用很簡單:可是效率並不高,由於只有幾種瀏覽器會遵循這個標記(那些真正會「讀懂」HTML的瀏覽器),沒有一種緩存代理服務器能遵循這個 規則(由於它們幾乎徹底不解析文檔中HTML內容);有事會在Web頁面中增長:Pragma: no-cache這個META標記,若是要讓頁面保持刷新,這個標籤其實徹底沒有必要。

  若是你的網站託管在ISP機房中,而且機房可能不給你權限去控制HTTP的頭信息(如:Expires和Cache-Control),大聲控訴:這些機制對於你的工做來講是必須的;

  另一方面: HTTP頭信息可讓你對瀏覽器和代理服務器如何處理你的副本進行更多的控制。他們在HTML代碼中是看不見的,通常由Web服務器自動生成。可是,根據 你使用的服務,你能夠在某種程度上進行控制。在下文中:你將看到一些有趣的HTTP頭信息,和如何在你的站點上應用部署這些特性。

 

  HTTP頭信息發送在HTML代碼以前,只有被瀏覽器和一些中間緩存能看到,一個典型的HTTP 1.1協議返回的頭信息看上去像這樣:

 

  HTTP/1.1 200 OK

 

  Date: Fri, 30 Oct 1998 13:19:41 GMT

 

  Server: Apache/1.3.3 (Unix)

  Cache-Control: max-age=3600, must-revalidate

  Expires: Fri, 30 Oct 1998 14:19:41 GMT

  Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT

 

  ETag: "3e86-410-3596fbbc"

  Content-Length: 1040

  Content-Type: text/html

 

  在頭信息空一行後是HTML代碼的輸出,關於如何設置HTTP頭信息請參考實現章節;

 

  Pragma HTTP頭信息 (爲何它不起做用)

 

  不少人認爲在HTTP頭信息中設置了Pragma: no-cache後會讓內容沒法被緩存。但事實並不是如此:HTTP的規範中,響應型頭信息沒有任何關於Pragma屬性的說明,而討論了的是請求型頭信息 Pragma屬性(頭信息也由瀏覽器發送給服務器),雖然少數集中緩存服務器會遵循這個頭信息,但大部分不會。用了Pragma也不起什麼做用,要用就使 用下列頭信息:

  使用Expires(過時時間)HTTP頭信息來控制保鮮期

  Expires(過時時間) 屬性是HTTP控制緩存的基本手段,這個屬性告訴緩存器:相關副本在多長時間內是新鮮的。過了這個時間,緩存器就會向源服務器發送請求,檢查文檔是否被修改。幾乎全部的緩存服務器都支持Expires(過時時間)屬性;

 

  大部分Web服務器支持你用幾種方式設置Expires屬性;通常的:能夠設計一個絕對時間間隔:基於客戶最後查看副本的時間(最後訪問時間)或者根據服務器上文檔最後被修改的時間;

 

  Expires頭信息:對於設置靜態圖片文件(例如導航欄和圖片按鈕)可緩存特別有用;由於這些圖片修改不多,你能夠給它們設置一個特別長的過時時間,這會使你的網站對用戶變得相應很是快;他們對於控制有規律改變的網頁也頗有用,例如:你天天早上6點更新新聞頁,你能夠設置副本的過時時間也是這個時間,這樣緩存 服務器就知道何時去取一個更新版本,而沒必要讓用戶去按瀏覽器的「刷新」按鈕。

  過時時間頭信息屬性值只能是HTTP格式的日期時間,其餘的都會被解析成當前時間「以前」,副本會過時,記住:HTTP的日期時間必須是格林威治時間(GMT),而不是本地時間。舉例:

 

  Expires: Fri, 30 Oct 1998 14:19:41 GMT

 

  因此使用過時時間屬性必定要確認你的Web服務器時間設置正確,一個途徑是經過網絡時間同步協議(Network Time Protocol NTP),和你的系統管理員那裏你能夠了解更多細節。

  雖然過時時間屬性很是有用,可是它仍是有些侷限,首先:是牽扯到了日期,這樣Web服務器的時間和緩存服務器的時間必須是同步的,若是有些不一樣步,要麼是應該緩存的內容提早過時了,要麼是過時結果沒及時更新。

 

  還有一個過時時間設置的問題也不容忽視:若是你設置的過時時間是一個固定的時間,若是你返回內容的時候又沒有連帶更新下次過時的時間,那麼以後全部訪問請求都會被髮送給源Web服務器,反而增長了負載和響應時間;

  Cache-Control(緩存控制) HTTP頭信息

  HTTP 1.1介紹了另一組頭信息屬性:Cache-Control響應頭信息,讓網站的發佈者能夠更全面的控制他們的內容,並定位過時時間的限制。

  有用的 Cache-Control響應頭信息包括:

 

  max-age=[秒] ― 執行緩存被認爲是最新的最長時間。相似於過時時間,這個參數是基於請求時間的相對時間間隔,而不是絕對過時時間,[秒]是一個數字,單位是秒:從請求時間開始到過時時間之間的秒數。

 

s-maxage=[秒] ― 相似於max-age屬性,除了他應用於共享(如:代理服務器)緩存

  public ― 標記認證內容也能夠被緩存,通常來講: 通過HTTP認證才能訪問的內容,輸出是自動不能夠緩存的;

  no-cache ― 強制每次請求直接發送給源服務器,而不通過本地緩存版本的校驗。這對於須要確認認證應用頗有用(能夠和public結合使用),或者嚴格要求使用最新數據的應用(不惜犧牲使用緩存的全部好處);

 

  no-store ― 強制緩存在任何狀況下都不要保留任何副本

 

  must-revalidate ― 告訴緩存必須遵循全部你給予副本的新鮮度的,HTTP容許緩存在某些特定狀況下返回過時數據,指定了這個屬性,你高速緩存,你但願嚴格的遵循你的規則。

  proxy-revalidate ― 和 must-revalidate相似,除了他只對緩存代理服務器起做用

  舉例:

 

  Cache-Control: max-age=3600, must-revalidate

  若是你計劃試用Cache-Control屬性,你應該看一下這篇HTTP文檔,詳見參考和深刻閱讀;

  校驗參數和校驗

  在Web緩存如何工做: 咱們說過:校驗是當副本已經修改後,服務器和緩存之間的通信機制;使用這個機制:緩存服務器能夠避免副本實際上仍然足夠新的狀況下重複下載整個原件。

  校驗參數很是重要,若是1個不存在,而且沒有任何信息說明保鮮期(Expires或Cache-Control)的狀況下,緩存將不會存儲任何副本;

 

  最多見的校驗參數是文檔的最後修改時間,經過最後Last-Modified頭信息能夠,當一份緩存包含Last-Modified信息,他基於此信息,經過添加一個If-Modified-Since請求參數,向服務器查詢:這個副本從上次查看後是否被修改了。

  HTTP 1.1介紹了另一個校驗參數: ETag,服務器是服務器生成的惟一標識符ETag,每次副本的標籤都會變化。因爲服務器控制了ETag如何生成,緩存服務器能夠經過If-None-Match請求的返回沒變則當前副本和原件徹底一致。

  全部的緩存服務器都使用Last-Modified時間來肯定副本是否夠新,而ETag校驗正變得愈來愈流行;

 

  全部新一代的Web服務器都對靜態內容(如:文件)自動生成ETag和Last-Modified頭信息,而你沒必要作任何設置。可是,服務器對於動態內容(例如:CGI,ASP或數據庫生成的網站)並不知道如何生成這些信息,參考一下編寫利於緩存的腳本章節;

 

  建立利於緩存網站的竅門

  除了使用新鮮度信息和校驗,你還有不少方法使你的網站緩存友好。

 

  保持URL穩定: 這是緩存的金科玉律,若是你給在不一樣的頁面上,給不一樣用戶或者從不一樣的站點上提供相同的內容,應該使用相同的URL,這是使你的網站緩存友好最簡單,也是 最高效的方法。例如:若是你在頁面上使用 "/index.html" 作爲引用,那麼就一直用這個地址;

 

  使用一個共用的庫存放每頁都引用的圖片和其餘頁面元素;

 

  對於不常常改變的圖片/頁面啓用緩存,並使用Cache-Control: max-age屬性設置一個較長的過時時間;

 

  對於按期更新的內容設置一個緩存服務器可識別的max-age屬性或過時時間;

 

  若是數據源(特別是下載文件)變動,修更名稱,這樣:你可讓其很長時間不過時,而且保證服務的是正確的版本;而連接到下載文件的頁面是一個須要設置較短過時時間的頁面。

  萬不得已不要改變文件,不然你會提供一個很是新的Last-Modified日期;例如:當你更新了網站,不要複製整個網站的全部文件,只上傳你修改的文件。

 

  只在必要的時候使用Cookie,cookie是很是難被緩存的,並且在大多數狀況下是沒必要要的,若是使用cookie,控制在動態網頁上;

 

  減小試用SSL,加密的頁面不會被任何共享緩存服務器緩存,只在必要的時候使用,而且在SSL頁面上減小圖片的使用;

  使用可緩存性評估引擎,這對於你實踐本文的不少概念都頗有幫助;

  編寫利於緩存的腳本

  腳本缺省不會返回校驗參數(返回Last-Modified或ETag頭信息)或其餘新鮮度信息(Expires或Cache-Control),有些動態腳本的確是動態內容(每次相應內容都不同),可是更多(搜索引擎,數據庫引擎網站)網站仍是能從緩存友好中獲益的。

 

  通常說來,若是腳本生成的輸出在將來一段時間(幾分鐘或者幾天)都是可重複複製的,那麼就是可緩存的。若是腳本輸出內容只隨URL變化而變化,也是可緩存的;但若是輸出會根據cookie,認證信息或者其餘外部條件變化,則仍是不可緩存的。

 

  最利於緩存的腳本就是將內容改變時導出成靜態文件,Web服務器能夠將其看成另一個網頁並生成和試用校驗參數,讓一些都變得更簡單,只須要寫入文件便可,這樣最後修改時間也有了;

  另一個讓腳本可緩存的方法是對一段時間內能保持較新的內容設置一個相對壽命的頭信息,雖然經過Expires頭信息也能夠實現,但更容易的是用Cache-Control: max-age屬性,它會讓首次請求後一段時間內緩存保持新鮮;

 

  若是以上作法你都作不到,你可讓腳本生成一個校驗屬性,並對 If-Modified-Since 和/或If-None-Match請求做出反應,這些屬性能夠從解析HTTP頭信息獲得,並對符合條件的內容返回304 Not Modified(內容未改變),惋惜的是,這種作法比不上前2種高效;

 

  其餘竅門:

 

  儘可能避免使用POST,除非萬不得已,POST模式的返回內容不會被大部分緩存服務器保存,若是你發送內容經過URL和查詢(經過GET模式)的內容能夠緩存下來供之後使用;

 

  不要在URL中加入針對每一個用戶的識別信息:除非內容是針對每一個用戶不一樣的;

 

  不要統計一個用戶來自一個地址的全部請求,由於緩存經常是一塊兒工做的;

 

  生成並返回Content-Length頭信息,若是方便的話,這個屬性讓你的腳本在可持續連接模式時:客戶端能夠經過一個TCP/IP連接同時請求多個副本,而不是爲每次請求單獨創建連接,這樣你的網站相應會快不少;

 

  具體定義請參考實現章節。

  常見問題解答

 

  讓網站變得可緩存的要點是什麼?

 

  好的策略是肯定那些內容最熱門,大量的複製(特別是圖片)並針對這些內容先部署緩存。

相關文章
相關標籤/搜索