閱讀903 返回首頁    go 人物


服務器網頁緩存的深入分析

Expires、Cache-Control、Last-Modified、ETag是RFC 2616(HTTP/1.1)協議中和網頁緩存相關的幾個字段。前兩個用來控製緩存的失效日期,後兩個用來驗證網頁的有效性。要注意的是, HTTP/1.0有一個功能比較弱的緩存控製機製:Pragma,使用HTTP/1.0的緩存將忽略Expires和Cache-Control頭。我們 這裏以Apache2.0服務器為例,隻討論HTTP/1.1協議。

Expires

Expires字段聲明了一個網頁或URL地址不再被瀏覽器緩存的時間,一旦超過了這個時間,瀏覽器都應該聯係原始服務器。RFC告訴我們:“由於推斷的失效時間也許會降低語義透明度,應該被謹慎使用,同時我們鼓勵原始服務器盡可能提供確切的失效時間。”

對於一般的純靜態頁麵,如html、gif、jpg、css、js,默認安裝的Apache服務器,不會在響應頭添加這個字段。Firefox瀏覽器接受 到相應後,如果發現沒有Expires字段,瀏覽器根據文件的類型和“Last-Modified”字段來推斷出一個合適的失效時間,並存儲在客戶端。推 測出的時間一般是接受到響應時間後的三天左右。

Apache的expires_module模塊可以在Http響應頭部自動加上Expires字段。在Apache的httpd.conf文件中進行如下配置:

#啟用expires_module模塊

LoadModule expires_module modules/mod_expires.so

# 啟用有效期控製

ExpiresActive On

# GIF有效期為1個月

ExpiresByType image/gif A2592000

# HTML文檔的有效期是最後修改時刻後的一星期

ExpiresByType text/html M604800

#以下的含義類似

ExpiresByType text/css “now plus 2 month”

ExpiresByType text/js “now plus 2 day”

ExpiresByType image/jpeg “access plus 2 month”

ExpiresByType image/bmp “access plus 2 month”

ExpiresByType image/x-icon “access plus 2 month”

ExpiresByType image/png “access plus 2 month”

對於動態頁麵,如果在頁麵內部沒有通過函數強製加上Expires,例如header(”Expires: ” . gmdate(”D, d M Y H:i:s”) . ” GMT”),Apache服務器會把Wed, 11 Jan 1984 05:00:00 GMT作為Expires字段內容,返回給瀏覽器。即認為動態頁麵總是失效的。而瀏覽器仍然會保存已經失效的動態頁麵。

可以發現Firefox瀏覽器總是緩存所有頁麵,不管失效、不失效還是沒有聲明失效時間。即使緩存中聲明了一個網頁的實效日期是 1970-01- 01 08:00:00,瀏覽器仍然會發送該文件在緩存中的Last-Modified和ETag字段。如果在服務器端驗證通過,返回304狀態,瀏覽器就還會 使用此緩存。

Cache-Control

Cache-Control字段中可以聲明多些元素,例如no-cache, must-revalidate, max-age=0等。這些元素用來指明頁麵被緩存最大時限,如何被緩存的,如何被轉換到另一個不同的媒介,以及如何被存放在持久媒介中的。但是任何一個 Cache-Control指令都不能保證隱私性或者數據的安全性。“private”和“no-store”指令可以為隱私性和安全性方麵提供一些幫 助,但是他們並不能用於替代身

份驗證和加密。

Apache的mod_cern_meta模塊允許文件級Http響應頭部的控製,同時它也可以配置Cache-Control頭(或任何其他頭)。響應 頭文件是放在原始目錄的子目錄中,根據原始文件名所命名的一個文件。具體用法請參閱Apache的官方網站。其中Cache-Control : max-age表示失效日期。如果沒有啟動mod_cern_meta模塊,Apache服務器會把Expires字段中的日期換算成以秒為單位的一個 delta值,賦值給max-age。如果啟動mod_cern_meta模塊,並且配置了max-age值,Apache會將這個覆蓋Expires字 段。同時,max-age隱含了Canche-Control: public。這樣瀏覽器接受到的Cache-Control : max-age和Expires值就是一致的。

如果失效日期Cache-Control : max-ag=0或者是負值,瀏覽器會在對應的緩存中把Expires設置為1970-01-01 08:00:00。

Last-Modified

Last-Modified和ETag是條件請求(Conditional Request)相關的兩個字段。如果一個緩存收到了針對一個頁麵的請求,它發送一個驗證請求詢問服務器頁麵是否已經更改,在HTTP頭裏麵帶上” ETag”和”If Modify Since”頭。服務器根據這些信息判斷是否有更新信息,如果沒有,就返回HTTP 304(NotModify);如果有更新,返回HTTP 200和更新的頁麵內容,並且攜帶新的”ETag”和”LastModified”。

使用這個機製,能夠避免重複發送文件給瀏覽器,不過仍然會產生一個HTTP請求。

一般純靜態頁麵本身都會有Last-Modified信息,Apache服務器會讀取頁麵文件中的Last-Modified信息,並添加到http響應頭部。

對於動態頁麵,如果在頁麵內部沒有通過函數強製加上Last-Modified,例如header(”Last-Modified: ” . gmdate(”D, d M Y H:i:s”) . ” GMT”),Apache服務器會把當前時間作為Last-Modified,返回給瀏覽器。

無論是純靜態頁麵還是動態頁麵,Firefox瀏覽器巧妙地按照接受到服務器響應的時間設置緩存頁麵的Last-Modified,而不是按照http響應頭部中的Last-Modified字段。

ETag

既然有了Last-Modified,為什麼還要用ETag字段呢?因為如果在一秒鍾之內對一個文件進行兩次更改,Last-Modified就會不正確。因此,HTTP/1.1利用Entity Tag頭提供了更加嚴格的驗證。

Apache服務器默認情況下,會對所有的靜態、動態文件的響應頭添加ETag字段。在Apache的httpd.conf文件中可以通過FileETag指令配置該選項。

FileETag指令配置了當文檔是基於一個文件時用以創建 Etag(entity tag)響應頭的文件的屬性。在Apache 1.3.22及以前,ETag的值是對文件的索引節(INode),大小(Size)和最後修改時間(MTime)進行Hash後得到的。如果一個目錄的 配置包含了‘FileETag INode MTime Size’而其一個子目錄包含了‘FileETag -INode’那麼這個子目錄的設置(並會被其下任何沒有進行覆蓋的子目錄繼承)將等價於‘FileETag MTime Size’。

在多台負載平衡的服務器環境下,同一個文件會有不同的etag或者文件修改日期,瀏覽器每次都會重新下載。設置‘FileETag None’可以使響應頭不再包含ETag字段。

三種典型web服務器Header設置內容過期方法

一、Internet 信息服務 (IIS)的內容過期設置

如果IIS 網站中有時間敏感信息,可以配置設置來保證過期信息不被代理服務器或 Web 瀏覽器緩存。可以配置網站內容,使之在任

何的時間自動過期。當啟用內容過期時,Web 瀏覽器將比較當前日期和截止日期,以便決定是顯示緩存頁還是從服務器請求更新的頁

。Microsoft ASP.NET 這樣的服務器端技術可用於動態更改提供的內容。通常,時間敏感信息隻限於單個文件、目錄或網站;不過,您也可以為某台計算機上的所有網站設置內容過期。

必須是本地計算機上 Administrators 組的成員或者必須被委派了相應的權限,才能執行下列步驟。作為安全性的最佳操作,請使用不屬於 Administrators 組的帳戶登錄計算機,然後使用運行方式命令以管理員身份運行 IIS管理器

在命令提示符下,鍵入 runas /user:administrative_accountname “mmc %systemroot%\system32\inetsrv\iis.msc”。

設置網站內容的過期時間

1. 在 IIS 管理器中,展開本地計算機;右鍵單擊要設置內容過期的網站、虛擬目錄或文件,然後單擊“屬性”。

2. 單擊“HTTP 頭”選項卡。

3. 選中“啟用內容過期”複選框。

4. 單擊“立即過期”、“此時間段後過期”或“過期時間”,然後在對應的框中輸入所需的過期信息。

5. 單擊“確定”。

二、APACHE服務的內容過期設置

Apache配置摘錄及解釋

i. 過期相關設置

LoadModule headers_module modules/mod_headers.so

#Load 修改header的模塊。

LoadModule expires_module modules/mod_expires.so

#Load 設定過期header的模塊。

Header append Via: CCN-BJ-4-502

#增加一個Via header,值配置成設備的hostname。

KeepAliveTimeout 60

#設置連接的保持時間為60秒。

ExpiresActive On

#啟用過期header功能。

ExpiresDefault A604800

#缺省過期時間為“訪問後的604800秒”

<Directory /data/download>

Options FollowSymLinks

AllowOverride None

Order allow,deny

Allow from all

ExpiresByType text/html A300

#text/html類型文件的過期設置為“訪問後的300秒”

ExpiresByType text/css A259200

#text/css類型文件的過期設置為“訪問後的259200秒”

ExpiresByType application/x-javascript A300

# application/x-javascript類型文件的過期設置為“訪問後的300秒”

ExpiresByType image/gif A2592000

#image/gif類型文件的過期設置為“訪問後的2592000秒”

ExpiresByType application/x-shockwave-flash A2592000

# application/x-shockwave-flash類型文件的過期設置為“訪問後的2592000秒”

</Directory>

上述配置文件中load的兩個模塊:mod_headers.so  和mod_expires.so 可以讓Apache具有對header的一些定製功能。

ExpiresByType:     表示按照文件類型-MIME-TYPE設定過期策略;

A300: 表示在Access後300秒後過期;

ExpiresByType text/css A2592000:    表示Mime type是text/css的文件,在Access後2592000秒過期。

ExpiresDefault A604800:  表示除了單獨製定的文件類型等過期策略外的其他內容,按照這個缺省的策略設定:訪問後604800秒過期。

上麵的方法可以實現根據web發布的不同文件類型,針對不同的發布目錄進行過期策略設置。在按照如上方法設置後,Apache會自動的產生兩個相關的http header,舉例如下:

HTTP/1.1 200 OK

Date: Tue, 27 Mar 2007 17:44:21 GMT

Server: Apache/2.0.54 (Unix)

Last-Modified: Thu, 25 Jan 2007 07:45:45 GMT

ETag: “72df3a-93-99499c40”

Accept-Ranges: bytes

Content-Length: 147

Cache-Control: max-age=2592000

Expires: Thu, 26 Apr 2007 17:44:21 GMT

Via: CCN-BJ-4-575

Keep-Alive: timeout=60, max=100

Connection: Keep-Alive

Content-Type: image/gif

Length: 147 [image/gif]

其中:Date + Max-age = Expires.  Max-age是個時間長度,對應web server上麵設置的過期時間;Expires是根據max-age算出來的過期時間點,兩者是一致的,不同cache在判斷內容是否過期時會嚴格比較 係統時間和上述過期時間,或者比較age(在cache中存住的時間長度)和max-age的值。

三、lighttpd

lighttpd默認是沒有開啟expire模塊的,需要我們在使用是手工開啟這個模塊支持。把mod_expire前麵的“#”號去掉。

# vi  /usr/local/lighttpd/etc/lighttpd.conf

“mod_expire”,

設定過期時間

* 設定指定url的過期時間:

expire.url = (

“/images/” => “access 3 hours”,

“/admin/” => “access 3 hours”,

“/area/” => “access 3 hours”,

“/calendar/” => “access 3 hours”,

“/common/” => “access 3 hours”,

“/front/” => “access 3 hours”,

“/inc/” => “access 3 hours”,

“/jeditor/” => “access 3 hours”,

“/js/” => “access 3 hours”,

“/script/” => “access 3 hours”,

“/theme/” => “access 3 hours”,

“/upload/” => “access 3 hours”,

“/view/” => “access 3 hours”,

“/help/” => “access 3 hours”,

“/htm/” => “access 5 minutes”

)

設置Etag

在配置文件中增加,etag.use-inode=”disable”(i節點不參與etag的運算),保證多台服務器生成的Etag值一致。

轉:https://www.yuanma.org/data/2007/0909/article_2851.htm

最後更新:2017-01-04 22:34:32

  上一篇:go 網頁加速的14條優化法則
  下一篇:go Lxadmin 開源vps控製麵板