1. 程式人生 > >面向站長和網站管理員的Web快取加速指南[翻譯] 原文(英文)地址: http://www.mnot.net/cache_docs/ 版權宣告:署名-非商業性使用-禁止演繹 2.0 這是一篇知識性

面向站長和網站管理員的Web快取加速指南[翻譯] 原文(英文)地址: http://www.mnot.net/cache_docs/ 版權宣告:署名-非商業性使用-禁止演繹 2.0 這是一篇知識性

什麼是Web快取,為什麼要使用它?

Web快取位於Web伺服器之間(1個或多個,內容源伺服器)和客戶端之間(1個或多個):快取會根據進來的請求儲存輸出內容的副本,例如html頁面, 圖片,檔案(統稱為副本),然後,當下一個請求來到的時候:如果是相同的URL,快取直接使用副本響應訪問請求,而不是向源伺服器再次傳送請求。

使用快取主要有2大理由:
  • 減少相應延遲:因為請求從快取伺服器(離客戶端更近)而不是源伺服器被相應,這個過程耗時更少,讓web伺服器看上去相應更快;
  • 減少網路頻寬消耗:當副本被重用時會減低客戶端的頻寬消耗;客戶可以節省頻寬費用,控制頻寬的需求的增長並更易於管理。

快取的型別

瀏覽器快取

對於新一代的Web瀏覽器來說(例如:IE,Firefox):一般都能在設定對話方塊中發現關於快取的設定,通過在你的電腦上僻處一塊硬碟空間用於儲存你已經看過的網站的副本。瀏覽器快取根據非常簡單的規則進行工作:在同一個會話過程中(在當前瀏覽器沒有被關閉之前)會檢查一次並確定快取的副本足夠新。這個快取對於使用者點選“後退”或者點選剛訪問過的連結特別有用,如果你瀏覽過程中訪問到同一個圖片,這些圖片可以從瀏覽器快取中調出而即時顯現。

代理伺服器快取

Web代理伺服器使用同樣的快取原理,只是規模更大。代理伺服器群為成百上千使用者服務使用同樣的機制;大公司和ISP經常在他們的防火牆上架設代理快取或者單獨的快取裝置;

由於帶路伺服器快取並非客戶端或者源伺服器的一部分,而是位於原網路之外,請求必須路由到他們才能起作用。一個方法是手工設定你的瀏覽器:告訴瀏覽器使用 那個代理,另外一個是通過中間伺服器:這個中間伺服器處理所有的web請求,並將請求轉發到後臺網路,而使用者不必配置代理,甚至不必知道代理的存在;

代理伺服器快取:是一個共享快取,不只為一個使用者服務,經常為大量使用者使用,因此在減少相應時間和頻寬使用方面很有效:因為同一個副本會被重用多次。

閘道器快取

也被稱為反向代理快取或間接代理快取,閘道器快取也是一箇中間伺服器,和內網管理員部署快取用於節省頻寬不同:閘道器快取一般是網站管理員自己部署:讓他們的網站更容易擴充套件並獲得更好的效能;
請求有幾種方法被路由到閘道器快取伺服器上:其中典型的是讓用一臺或多臺負載均衡伺服器從客戶端看上去是源伺服器;

網路內容釋出商  (Content delivery networks CDNs)分佈閘道器快取到整個(或部分)網際網路上,並出售快取服務給需要的網站,SpeederaAkamai就是典型的網路內容釋出商(下文簡稱CDN)。

本問主要關注於瀏覽器和代理快取,當然,有些資訊對於閘道器快取也同樣有效;

Web快取無害嗎?為什麼要鼓勵快取?

Web快取在網際網路上最容易被誤解的技術之一:網站管理員經常怕對網站失去控制,由於代理快取會“隱藏”他們的使用者,讓他們感覺難以監控誰在使用他們的網站。
不幸的是:就算不考慮Web快取,網際網路上也有很多網站使用非常多的引數以便管理員精確地跟蹤使用者如何使用他們的網站;如果這類問題也是你關心的,本文將告訴你如何獲得精確的統計而不必將網站設計的非常快取不友好。
另外一個抱怨是快取會給使用者過期或失效的資料;無論如何:本文可以告訴你怎樣配置你的伺服器來控制你的內容將被如何快取。

CDN是另外一個有趣的方向,和其他代理快取不同:CDN的閘道器快取為希望被快取的網站服務,沒有以上顧慮。即使你使用了CDN,你也要考慮後續的代理伺服器快取和瀏覽器快取問題。

另外一方面:如果良好地規劃了你的網站,快取會有助於網站服務更快,並節省伺服器負載和網際網路的連結請求。這個改善是顯著的:一個難以快取的網站可能需要幾秒去載入頁面,而對比有快取的網站頁面幾乎是即時顯現:使用者更喜歡速度快的網站並更經常的訪問;

這樣想:很多大型網際網路公司為全世界伺服器群投入上百萬資金,為的就是讓使用者訪問儘可能快,客戶端快取也是這個目的,只不過更靠近使用者一端,而且最好的一點是你甚至根本不用為此付費。

事實上,無論你是否喜歡,代理伺服器和瀏覽器都回啟用快取。如果你沒有配置網站正確的快取,他們會按照預設或者快取管理員的策略進行快取。

快取如何工作

所有的快取都用一套規則來幫助他們決定什麼時候使用快取中的副本提供服務(假設有副本可用的情況下);一些規則在協議中有定義(HTTP協議1.0和1.1),一些規則由快取的管理員設定(瀏覽器的使用者或者代理伺服器的管理員);
一般說來:遵循以下基本的規則(不必擔心,你不必知道所有的細節,細節將隨後說明)

  1. 如果響應頭資訊:告訴快取器不要保留快取,快取器就不會快取相應內容;
  2. 如果請求資訊是需要認證或者安全加密的,相應內容也不會被快取;
  3. 如果在迴應中不存在校驗器(ETag或者Last-Modified頭資訊),快取伺服器會認為缺乏直接的更新度資訊,內容將會被認為不可快取。
  4. 一個快取的副本如果含有以下資訊:內容將會被認為是足夠新的
    • 含有完整的過期時間和壽命控制頭資訊,並且內容仍在保鮮期內;
    • 瀏覽器已經使用過快取副本,並且在一個會話中已經檢查過內容的新鮮度;
    • 快取代理伺服器近期內已經使用過快取副本,並且內容的最後更新時間在上次使用期之前;
    • 夠新的副本將直接從快取中送出,而不會向源伺服器傳送請求;
  5. 如果快取的副本已經太舊了,快取伺服器將向源伺服器發出請求校驗請求,用於確定是否可以繼續使用當前拷貝繼續服務;
總之:新鮮度校驗是確定內容是否可用的最重要途徑:

如果副本足夠新,從快取中提取就立刻能用了;
而經快取器校驗後發現副本的原件沒有變化,系統也會避免將副本內容從源伺服器整個重新傳輸一遍。

如何控制(控制不)快取

有很多工具可以幫助設計師和網站管理員調整快取伺服器對待網站的方式,這也許需要你親自下手對伺服器的配置進行一些調整,但絕對值得;瞭解如何使用這些工具請參考後面的實現章節;

HTML meta標籤和HTTP 頭資訊

HTML的編寫者會在文件的<HEAD>區域中加入描述文件的各種屬性,這些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連結同時請求多個副本,而不是為每次請求單獨建立連結,這樣你的網站相應會快很多;
具體定義請參考實現章節。

常見問題解答

讓網站變得可快取的要點是什麼?

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

如何讓頁面通過快取達到最快相應?

快取最好的副本是那些可以長時間保持新鮮的內容;基於校驗雖然有助於加快相應,但是它不得不和源伺服器聯絡一次去檢查內容是否夠新,如果快取伺服器上就知道內容是新的,內容就可以直接相應返回了。

我理解快取是好的,但是我不得不統計多少人訪問了我的網站!

如果你必須知道每次頁面訪問的,選擇【一】個頁面上的小元素,或者頁面本身,通過適當的頭資訊讓其不可快取,例如: 可以在每個頁面上部署一個1x1畫素的透明圖片。Referer頭資訊會有包含這個圖片的每個頁面資訊;
明確一點:這個並不會給你一個關於你使用者精確度很高的統計,而且這對網際網路和你的使用者這都不太好,消耗了額外的頻寬,強迫使用者去訪問無法快取的內容。瞭解更多資訊,參考訪問統計資料。

我如何能看到HTTP頭資訊的內容?

很多瀏覽器在頁面屬性或類似介面中可以讓你看到Expires 和Last-Modified資訊;如果有的話:你會找到頁面資訊的選單和頁面相關的檔案(如圖片),並且包含他們的詳細資訊;
看到完整的頭資訊,你可以用telnet手工連線到Web伺服器;
為此:你可能需要用一個欄位指定埠(預設是80),或者連結到www.example.com:80 或者 www.example.com 80(注意是空格),更多設定請參考一下telnet客戶端的文件;
開啟網站連結:請求一個檢視連結,如果你想看到http://www.example.com/foo.html 連線到www.example.com的80埠後,鍵入:

GET /foo.html HTTP/1.1 [回車]
GET /foo.html HTTP/1.1 [return]
Host: www.example.com [回車][回車] 
Host: www.example.com [return][return]

在[回車]處按鍵盤的回車鍵;在最後,要按2次回車,然後,就會輸出頭資訊及完整頁面,如果只想看頭資訊,將GET換成HEAD。

我的頁面是密碼保護的,代理快取伺服器如何處理他們?

預設的,網頁被HTTP認證保護的都是私密內容,它們不會被任何共享快取保留。但是,你可以通過設定Cache-Control: public讓認證頁面可快取,HTTP 1.1標準相容的快取伺服器會認出它們可快取。
如果你認為這些可快取的頁面,但是需要每個使用者認證後才能看,可以組合使用Cache-Control: public和no-cache頭資訊,快取記憶體必須在提供副本之前,將將新客戶的認證資訊提交給源伺服器。設定就是這樣:

Cache-Control: public, no-cache

無論如何:這是減少認證請求的最好方法,例如: 你的圖片是不機密的,將它們部署在另外一個目錄,並對此配置伺服器不強制認證。這樣,那些圖片會預設都快取。

我們是否要擔心使用者通過cache訪問我的站點?

代理伺服器上SSL頁面不會被快取(不推薦被快取),所以你不必為此擔心。但是,由於快取儲存了非SSL請求和從他們抓取的URL,你要意識到沒有安全保護的網站,可能被不道德的管理員可能蒐集使用者隱私,特別是通過URL。
實際上,位於伺服器和客戶端之間的管理員可以蒐集這類資訊。特別是通過CGI指令碼在通過URL傳遞使用者名稱和密碼的時候會有很大問題;這對洩露使用者名稱和密碼是一個很大的漏洞;
如果你初步懂得網際網路的安全機制,你不會對快取伺服器有任何。

我在尋找一個包含在Web釋出系統解決方案,那些是比較有快取意識的系統?

這很難說,一般說來系統越複雜越難快取。最差就是全動態釋出並不提供校驗引數;你無發快取任何內容。可以向系統提供商的技術人員瞭解一下,並參考後面的實現說明。

我的圖片設定了1個月後過期,但是我現在需要現在更新。

過期時間是繞不過去的,除非快取(瀏覽器或者代理伺服器)空間不足才會刪除副本,快取副本在過期之間會被一直使用。
最好的辦法是改變它們的連結,這樣,新的副本將會從源伺服器上重新下載。記住:引用它們的頁面本身也會被快取。因此,使用靜態圖片和類似內容是很容易快取的,而引用他們的HTML頁面則要保持非常更新;
如果你希望對指定的快取伺服器重新載入一個副本,你可以強制使用“重新整理”(在FireFox中在reload的時候按住shift鍵:就會有前面提到惡Pragma: no-cache頭資訊發出)。或者你可以讓快取的管理員從他們的介面中刪除相應內容;

我執行一個Web託管服務,如何讓我的使用者釋出快取友好的網頁?

如果你使用apahe,可以考慮允許他們使用.htaccess檔案並提供相應的文件;
另外一方面: 你也可以考慮在各種虛擬主機上建立各種快取策略。例如: 你可以設定一個目錄 /cache-1m 專門用於存放訪問1個月的訪問,另外一個 /no-cache目錄則被用提供不可儲存副本的服務。
無論如何:對於大量使用者訪問還是應該用快取。對於大網站,這方面的節約很明顯(頻寬和伺服器負載);

我標記了一些網頁是可快取的,但是瀏覽器仍然每次傳送請求給服務。如何強制他們儲存副本?

快取伺服器並不會總儲存副本並重用副本;他們只是在特定情況下會不儲存並使用副本。所有的快取伺服器都回基於檔案的大小,型別(例如:圖片 頁面),或者伺服器空間的剩餘來確定如何快取。你的頁面相比更熱門或者更大的檔案相比,並不值得快取。
所以有些快取伺服器允許管理員根據檔案型別確定快取副本的優先順序,允許某些副本被永久快取並長期有效;

快取機制的實現 - Web伺服器端配置

一般說來,應該選擇最新版本的Web伺服器程式來部署。不僅因為它們包含更多利於快取的功能,新版本往往在效能和安全性方面都有很多的改善。

Apache HTTP伺服器

Apache有些可選的模組來包含這些頭資訊: 包括Expires和Cache-Control。 這些模組在1.2版本以上都支援;
這些模組需要和apache一起編譯;雖然他們已經包含在釋出版本中,但預設並沒有啟用。為了確定相應模組已經被啟用:找到httpd程式並執行httpd -l 它會列出可用的模組,我們需要用的模組是mod_expires和mod_headers

  • 如果這些模組不可用,你需要聯絡管理員,重新編譯幷包含這些模組。這些模組有時候通過配置檔案中把註釋掉的配置啟用,或者在編譯的時候增加-enable -module=expires和-enable-module=headers選項(在apache 1.3和以上版本)。 參考Apache釋出版中的INSTALL檔案;

Apache一旦啟用了相應的模組,你就可以在.htaccess檔案或者在伺服器的access.conf檔案中通過mod_expires設定副本什 麼時候過期。你可設定過期從訪問時間或檔案修改時間開始計算,並且應用到某種檔案型別上或預設設定,參考模組的文件獲得更多資訊,或者遇到問題的時候向你身邊的apache專家討教。
應用Cache-Control頭資訊,你需要使用mod_headers,它將允許你設定任意的HTTP頭資訊,參考mod_headers的文件可以獲得更多資料;
這裡有個例子說明如何使用頭資訊:

  • .htaccess檔案允許web釋出者使用命令只在配置檔案中用到的命令。他影響到所在目錄及其子目錄;問一下你的伺服器管理員確認這個功能是否啟用了。 
### 啟用 mod_expires
ExpiresActive On
### 設定 .gif 在被訪問過後1個月過期。
ExpiresByType image/gif A2592000
### 其他檔案設定為最後修改時間1天后過期
### (用了另外的語法)
ExpiresDefault "modification plus 1 day"
### 在index.html檔案應用 Cache-Control頭屬性
<Files index.html>
Header append Cache-Control "public, must-revalidate"
</Files>        
  • 注意: 在適當情況下mod_expires會自動計算並插入Cache-Control:max-age 頭資訊

Microsoft IIS伺服器

Microsoft的IIS可以非常容易的設定頭資訊,注意:這隻針對IIS 4.0伺服器,並且只能在NT伺服器上執行。
為網站的一個區域設定頭資訊,先要到管理員工具介面中,然後設定屬性。選擇HTTP Header選單,你會看到2個有趣的區域:啟用內容過期和定製HTTP頭資訊。頭一個設定會自動配置,第二個可以用於設定Cache-Control頭資訊;
設定asp頁面的頭資訊可以參考後面的ASP章節,也可以通過ISAPI模組設定頭資訊,細節請參考MSDN。

Netscape/iPlanet企業伺服器

3.6版本以後,Netscape/iPlanet已經不能設定Expires頭資訊了,他從3.0版本開始支援HTTP 1.1的功能。這意味著HTTP 1.1的快取(代理伺服器/瀏覽器)優勢都可以通過你對Cache-Control設定來獲得。
使用Cache-Control頭資訊,在管理伺服器上選擇內容管理|快取設定目錄。然後:使用資源選擇器,選擇你希望設定頭資訊的目錄。設定完頭資訊後,點選“OK”。更多資訊請參考Netscape/iPlanet企業伺服器的手冊

快取機制的實現:伺服器端指令碼

需要注意的一點是:也許伺服器設定HTTP頭資訊比指令碼語言更容易,但是兩者你都應該使用。
因為伺服器端的指令碼主要是為了動態內容,他本身不產生可快取的檔案頁面,即使內容實際是可以快取的。如果你的內容經常改變,但是不是每次頁面請求都改變, 考慮設定一個Cache-Control: max-age頭資訊;大部分使用者會在短時間內多次訪問同一頁面。例如: 使用者點選“後退”按鈕,即使沒有新內容,他們仍然要再次從伺服器下載內容檢視。

CGI程式

CGI指令碼是生成內容最流行的方式之一,你可以很容易在傳送內容之前的擴充套件HTTP頭資訊;大部分CGI實現都需要你寫 Content-Type頭資訊,例如這個Perl指令碼:

#!/usr/bin/perl
print "Content-type: text/html\n";
print "Expires: Thu, 29 Oct 1998 17:04:19 GMT\n";
print "\n";
### 後面是內容體...

由於都是文字,你可以很容易通過內建函式生成Expires和其他日期相關的頭資訊。如果你使用Cache-Control: max-age;會更簡單;

print "Cache-Control: max-age=600\n";

這樣指令碼可以在被請求後快取10分鐘;這樣使用者如果按“後退”按鈕,他們不會重新提交請求;
CGI的規範同時也允許客戶端傳送頭資訊,每個頭資訊都有一個‘HTTP_’的字首;這樣如果一個客戶端傳送一個If-Modified-Since請求,就是這樣的:

HTTP_IF_MODIFIED_SINCE = Fri, 30 Oct 1998 14:19:41 GMT 


參考一下cgi_buffer庫,一個自動處理ETag的生成和校驗的庫,生成Content-Length屬性和對內容進行gzip壓縮。在Python指令碼中也只需加入一行;

伺服器端包含 Server Side Includes

SSI(經常使用.shtml副檔名)是網站釋出者最早可以生成動態內容的方案。通過在頁面中設定特別的標記,也成為一種嵌入HTML的指令碼;
大部分SSI的實現無法設定校驗器,於是無法快取。但是Apache可以通過對特定檔案的組執行許可權設定實現允許使用者設定那種SSI可以被快取;結合XbitHack調整整個目錄。更多文件請參考mod_include文件

PHP

PHP是一個內建在web伺服器中的伺服器端指令碼語言,當做為HTML嵌入式指令碼,很像SSI,但是有更多的選項,PHP可以在各種Web伺服器上設定為CGI模式執行,或者做為Apache的模組;
預設PHP生成副本沒有設定校驗器,於是也無法快取,但是開發者可以通過Header()函式來生成HTTP的頭資訊;
例如:以下程式碼會生成一個Cache-Control頭資訊,並設定為3天以後過期的Expires頭資訊;

<?php
 Header("Cache-Control: must-revalidate");

 $offset = 60 * 60 * 24 * 3;
 $ExpStr = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
 Header($ExpStr);
?>

記住: Header()的輸出必須先於所有其他HTML的輸出;
正如你看到的:你可以手工建立HTTP日期;PHP沒有為你提供專門的函式(新版本已經讓這個越來越容易了,請參考PHP的日期相關函式文件),當然,最簡單的還是設定Cache-Control: max-age頭資訊,而且對於大部分情況都比較適用;
更多資訊,請參考header相關的文件
也請參考一下cgi_buffer庫,自動處理ETag的生成和校驗,Content-Length生成和內容的gzip壓縮,PHP指令碼只需包含1行程式碼;

Cold Fusion

Cold Fusion是Macromedia的商業伺服器端指令碼引擎,並且支援多種Windows平臺,Linux平臺和多種Unix平臺。Cold Fusion通過CFHEADER標記設定HTTP頭資訊相對容易。可惜的是:以下的Expires頭資訊的設定有些容易誤導;

<CFHEADER NAME="Expires" VALUE="#Now()#">

它並不像你想像的那樣工作,因為時間(本例中為請求發起的時間)並不會被轉換成一個符合HTTP時間,而且打印出副本的Cold fusion的日期/時間物件,大部分客戶端會忽略或者將其轉換成1970年1月1日。
但是:Cold Fusion另外提供了一套日期格式化函式, GetHttpTimeSTring. 結合DateAdd函式,就很容易設定過期時間了,這裡我們設定一個Header宣告副本在1個月以後過期;

<cfheader name="Expires" value="#GetHttpTimeString(DateAdd('m', 1, Now()))#">

你也可以使用CFHEADER標籤來設定Cache-Control: max-age等其他頭資訊;
記住:Web伺服器也會將頭資訊設定轉給Cold Fusion(做為CGI執行的時候),檢查你的伺服器設定並確定你是否可以利用伺服器設定代替Cold Fusion。 

ASP和ASP.NET

在asp中設定HTTP頭資訊是:確認Response方法先於HTML內容輸出前被呼叫,或者使用 Response.Buffer暫存輸出;同樣的:注意某些版本的IIS預設設定會輸出Cache-Control: private 頭資訊,必須宣告成public才能被共享快取伺服器快取。
IIS的ASP和其他web伺服器都允許你設定HTTP頭資訊,例如: 設定過期時間,你可以設定Response物件的屬性;

<% Response.Expires=1440 %>

設定請求的副本在輸出的指定分鐘後過期,類似的:也可以設定絕對的過期時間(確認你的HTTP日期格式正確)

<% Response.ExpiresAbsolute=#May 31,1996 13:30:15 GMT# %>

Cache-Control頭資訊可以這樣設定:

<% Response.CacheControl="public" %>

在ASP.NET中,Response.Expires 已經不推薦使用了,正確的方法是通過Response.Cache設定Cache相關的頭資訊;

Response.Cache.SetExpires ( DateTime.Now.AddMinutes ( 60 ) ) ;
Response.Cache.SetCacheability ( HttpCacheability.Public ) ;

參考MSDN文件可以找到更多相關新年系;

參考文件和深入閱讀

HTTP 1.1的規範有大量的擴充套件用於頁面快取,以及權威的介面實現指南,參考章節:13, 14.9, 14.21, 以及 14.25.

非常精彩的介紹快取相關概念,並介紹其他線上資源。

Jeff Goldberg內容豐富的演說告訴你為什麼不應該過度依賴訪問統計和計數器;

可快取的引擎設計,檢測網頁並確定其如何與Web快取伺服器互動, 這個引擎配合這篇指南是一個很好的除錯工具,

包含庫:用於CGI模式執行的Perl/Python/PHP指令碼,自動處理ETag生成/校驗,Content-Length生成和內容壓縮。正確地。 Python版本也被用作其他大量的CGI指令碼。

關於本文件

本文版權屬於Mark Nottingham <[email protected]>,本作品遵循創作共用版權
如果你映象本文,請通過以上郵件告知,這樣你可以在更新時被通知;
所有的商標屬於其所有人。
雖然作者確信內容在釋出時的正確性,但不保證其應用或引申應用的正確性,如有誤傳,錯誤或其他需要澄清的問題請儘快告知作者;
本文最新版本可以從 http://www.mnot.net/cache_docs/ 獲得;
翻譯版本包括: 捷克語版法語版中文版
版本: 1.81 - 2007年3月16日

翻譯: 車東 2007年9月6日

相關推薦

面向站長網站管理員Web快取加速指南[翻譯] 原文英文地址 http://www.mnot.net/cache_docs/ 版權宣告署名-商業性使用-禁止演繹 2.0 知識性

什麼是Web快取,為什麼要使用它? Web快取位於Web伺服器之間(1個或多個,內容源伺服器)和客戶端之間(1個或多個):快取會根據進來的請求儲存輸出內容的副本,例如html頁面, 圖片,檔案(統稱為副本),然後,當下一個請求來到的時候:如果是相同的URL,快取直接使用副本響應訪問請求,而不是向源伺服器再次

Android開發之顯示弄懂ppi、dpi、pt、px、dp、dip、sp之間的關係看就夠了

版權申明】非商業目的註明出處可自由轉載 博文地址:https://blog.csdn.net/ShuSheng0007/article/details/85165773 出自:shusheng007 文章目錄 概述 要解決的疑問 概念篇

【轉】【修真院“善良”系列之十八】WEB程序員從零開始到就業的全資料V1.0——只看就夠了!

absolute feed 自己 session rem 好的 ans 一個 css樣式 這是兩年以來,修真院收集整理的學習資料順序。以CSS15個任務,JS15個任務為基礎,分別依據要完成任務的不同的技能點,我們整理出來了這麽一篇在學習的時候需要看到的資料。這是Versi

易學筆記--ServletJSP--入門就看就夠了

第4章:作為Servlet:請求和響應/4.1 Servlet載入過程 第4章:作為Servlet:請求和響應/4.2 請求 第4章:作為Servlet:請求和響應/4.3 響應 第4章:作為Servlet:請求和響應/4.4 資源下載例項 第4章:作為Servlet:

JVM垃圾回收面試入門,就夠了

前些天在 google 上搜索了一些JVM的參考資料,偶然發現了一篇文章,如獲至寶,簡單易懂而且相對全面的JVM和垃圾回收介紹寫得非常的棒,因此一直儲存著,今天有時間特意翻譯了一下。本人水平有限,但是遇到好文章希望可以與更多的人分享,特此釋出此文。 英文OK的話

Web全棧“攻城獅”的快速養成你可不能錯過!

在開發一個WEB專案的時候,要經過三層結構:   顯示層:網站的前端的架構,負責網站介面一類的問題; 邏輯處理層:網站的後臺架構,負責資料的動態處理; 資料庫處理層:通過資料庫語句和API來為網站進行資料的處理與提供; 基本的三層結構圖

[原創]分散式系統之快取的微觀應用經驗談【資料分片叢集

分散式系統之快取的微觀應用經驗談(三)【資料分片和叢集篇】 前言   近幾個月一直在忙些瑣事,幾乎年後都沒怎麼閒過。忙忙碌碌中就進入了2018年的秋天了,不得不感嘆時間總是如白駒過隙,也不知道收穫了什麼和失去了什麼。最近稍微休息,買了兩本與技術無關的書,其一是 Yann Martel 寫的《The

容器中 Java 應用程式的記憶體 CPU 如何分配?看就夠了!

出品丨Docker公司(ID:docker-cn)編譯丨小東每週一、三、五,與您不見不散! 隨著2018年的結束,我們將回顧排名前五的最受讀者歡迎的文章。今天分享的第一篇文章,將幫助那些在容器中執行 Java 虛擬機器(JVM)時遇到記憶體和 CPU 大小調整/使用困難的人,本文將解釋如何在 D

Java 中的 override overload 運算,看就夠

問題出現: 即使對於一個經驗豐富的開發人員來說,方法過載和方法覆蓋的區別都能讓他猶豫一下, 對於新手來說,經常容易弄混淆。 有沒有比較深入淺出的理解方式,能讓人過目不忘,用起來還能有條件反射般的速度呢? 其他人是怎麼做的: 寫類似比較的部落格非常之多,無非也就是分開介紹,然後比較區別

Java 中的 override overload,看就夠

urn 兼容性 return com 容易 定義 erl ext class 問題出現: 即使對於一個經驗豐富的開發人員來說,方法重載和方法覆蓋的區別都能讓他猶豫一下, 對於新手來說,經常容易弄混淆。 有沒有比較深入淺出的理解方式,能讓人過目不忘,用起來還能有條件反射般的

js節流防抖別看

  前言:我們在做頁面事件繫結的時候,經常要進行節流處理,比如滑鼠非同步點選,去執行一個非同步請求時,需要讓它在上一次沒執行時不能再點選,又或者繫結滾動事件,這種持續觸發進行dom判斷的時候,就要按一定頻率的執行。 一、 偽理論:      概念: 節流和防抖我認為都可以

關於AIDL使用Binder機制詳解,你只需要看即可

本篇文章從AIDL的角度來闡述Binder機制呼叫遠端服務的內部執行原理。因此本篇文章的第一部分介紹AIDL的使用,第二部分從AIDL的使用上具體介紹Binder機制。關於Binder機制的原理,可以參考簡單理解Binder機制的原理,對其有個大概的瞭解。 一、AIDL

Squid2.5-2.6的改進以及反向代理實現Web快取加速

Squid2.6反向代理實現Web快取加速 主要的改進  1、融合加速和反向功能 Major improvements to the way that Squid handles web proxy, accelerated and transparent proxy re

架設Squid代理作為WEB快取加速

在區域網的路由伺服器中假設Squid代理來統一管理並加速內網機器對外部網路的訪問速度。 下載並安裝Squid 1、從伺服器下載tar包。 wget http://www.squid-cache.org/Versions/v3/3.5/squid-3.5

關於Mysql的事務鎖 看文章就夠了

鎖共享讀鎖(S鎖)和 排他寫鎖(X鎖)行鎖與表鎖innodb用的是行級鎖,相對於表鎖來說效能開銷會更大。雖然叫做行級鎖,但不表示他只鎖住修改的行記錄,即使找不到行記錄,他也會產生鎖。innodb 是根據掃描範圍來鎖定行記錄,如果有索引,那麼只會鎖定索引的覆蓋範圍,如果找不到索

友盟分享推送看就夠了

前段時間寫了一篇關於友盟推送的文章,從閱讀量來看,大家在這方面踩了很多坑,所以我覺得有必要來個全面的總結,給大家更好的過坑意見; 先從分享開始說吧 第一步整合SDK:官方文件說的很詳細了,整合大家就看文件吧,我就總結一下要注意的地方: 微信,qq,簡訊等友盟的api都有了

Python虛擬環境包管理工具Pipenv的使用詳解--看完就夠了

依賴 交互 -- 速度 插入圖片 proc HERE 科技 常用命令 前言 Python虛擬環境是一個虛擬化,從電腦獨立開辟出來的環境。在這個虛擬環境中,我們可以pip安裝各個項目不同的依賴包,從全局中隔離出來,利於管理。 傳統的Python虛擬環境有virtualenv,

弄明白CMSG1,就靠

目錄 1 CMS收集器 安全點(Safepoint) 安全區域 2 G1收集器 卡表(Card Table) 3 總結 4

JS作用域變數提升看就夠了

作用域是JS中一個很基礎但是很重要的概念,面試中也經常出現,本文會詳細深入的講解這個概念及其他相關的概念,包括宣告提升,塊級作用域,作用域鏈及作用域鏈延長等問題。 ## 什麼是作用域 第一個問題就是我們要弄清楚什麼是作用域,這不是JS獨有的概念,而是程式設計領域中通用的一個概念。我們以下面這個語句為例:

【Spring註解驅動開發】如何使用@Bean註解指定初始化銷燬的方法?看就夠了!!

## 寫在前面 > 在【[String註解驅動開發專題](https://www.cnblogs.com/binghe001/category/1780611.html)】中,前面的文章我們主要講了有關於如何向Spring容器中註冊bean的知識,大家可以到【[String註解驅動開發專題](http