1. 程式人生 > >HTTP Cache 總結及Nginx Cache配置

HTTP Cache 總結及Nginx Cache配置

轉自

簡介

先說一下我對快取的理解:快取可以讓使用者更加接近資料。HTTP快取指我們用瀏覽器訪問網站時,根據伺服器返回的HTTP快取響應頭設定,快取相應的資料,下次訪問就可以直接使用,或者去伺服器驗證資料是否過期。這樣可以大大減輕寬頻壓力,加快網頁載入速度。

相關頭部

當我們首次訪問http://www.2cto.com/uploadfile/2016/1008/20161008090645827.jpg 時,得到如下響應頭:
在這裡插入圖片描述
伺服器返回如下幾個快取控制頭部:

  • Last-Modified:表示文件的最後修改時間,當去伺服器驗證時會拿這個時間去;
  • Expires:http/1.0規範定義,表示文件在瀏覽器中的過期時間,當快取的內容超過這個時間則需要重新去伺服器獲取最新的內容;
  • Cache-Control:http/1.1規範定義,表示瀏覽器快取控制,max-age=3153600表示文件可以在瀏覽器中快取一年。
  • ETag:傳送到服務端進行內容變更驗證的,而Catch-Control是用於控制快取時間的(瀏覽器、代理層等)。此處我們使用了弱實體W\”6124c”,弱實體(”6124c”)只要內容語義沒變即可,比如內容的gzip版和非gzip版可以使用弱實體驗證;而強實體指位元組必須完全一致(gzip和非gzip情況是不一樣的),因此建議首先選擇使用弱實體。

nginx在生成etag時使用的演算法是Last-Modified + Content-Length計算的。根據規範定義Cache-Control優先順序高於Expires,實際使用時可以兩個都用,或僅使用Cache-Control就可以了。一般情況下Expires=當前系統時間(Date) + 快取時間(Cache-Control: max-age)。

當我們再次訪問http://www.2cto.com/uploadfile/2016/1008/20161008090645827.jpg 時,發現瀏覽器請求頭部有變化:
在這裡插入圖片描述

  1. Modified-Since請求頭,其值是上次請求響應中的Last-Modified,即瀏覽器會拿這個時間去服務端驗證內容是否發生了變更。

  2. If-None-Match請求頭,其值是上次請求響應中的ETag,即瀏覽器會拿這個時間去服務端驗證內容是否發生了變更。

Last-Modified與ETag同時使用時,瀏覽器在驗證時會同時傳送If-Modified-Since和If-None-Match,按照http/1.1規範,如果同時使用If-Modified-Since和If-None-Match則服務端必須兩個都驗證通過後才能返回304;且nginx就是這樣做的。因此實際使用時應該根據實際情況選擇。

當我們按下cmd-F5強制重新整理後:
在這裡插入圖片描述

瀏覽器在請求時不會帶上If-Modified-Since,並帶上Cache-Control:no-cache和Pragma:no-cache,這是為了告訴服務端說我請給我一份最新的內容。

相關狀態碼

304 Not Modified

在這裡插入圖片描述

304表示伺服器返回文件沒有過期

200 (from cache)

在這裡插入圖片描述

200 (from cache) 表示瀏覽器直接使用快取資料

總結

Last-Modified/Modified-Since 用於驗證文件內容是否變更 max-age/Expires 定義文件快取時間,如在有效期內會返回 200(from cache)

Nginx 作為靜態檔案伺服器

主要配置:

expires:控制Expires響應頭
etag (off):控制是否返回Etag響應頭
if-modified-since (before/exact): exact表示精確匹配,before表示檔案修改時間早於瀏覽器If-Modified-Since時間,就返回304

靜態檔案配置:

在這裡插入圖片描述

Nginx作為反向代理

nginx作為反向代理,所有請求都會先請求至nginx,再由nginx轉發

在這裡插入圖片描述

如果使用Expires可以修改返回瀏覽器Expires頭部資訊,但是nginx只負責轉發請求和負載均衡,沒有為後端伺服器分擔壓力。

這是我們需要nginx在本地對訪問內容進行快取,如果檔案還在快取期內,由nginx返回304響應,否則再轉發至後臺,並且nginx再次更新自己的本地快取。

nginx本地快取http配置

在這裡插入圖片描述
主要介紹下proxy_cache_path配置

  • levels:表示建立兩級目錄結構,比如/export/cache/proxy_cache//*/,將所有檔案放在一級目錄結構中如果檔案量很大會導致訪問檔案效率低。
    keys_zone:設定儲存所有快取key和相關資訊的共享記憶體區,1M大約能儲存8000個key。
  • inactive:inactive指定被快取的內容多久不被訪問將從快取中移除,以保證內容的新鮮;預設10分鐘。
  • max_size :最大快取閥值,“cachemanager”程序會監控最大快取大小,當快取達到該閥值,該程序將從快取中移除最近最少使用的內容。
  • use_temp_path:如果為on,則內容首先被寫入臨時檔案(proxy_temp_path ),然後重新命名到proxy_cache_path指定的目錄;如果設定為off,則內容直接被寫入到proxy_cache_path指定的目錄。

nginx本地快取location配置

在這裡插入圖片描述

  • proxy_cache :指定使用哪個共享記憶體區域儲存快取鍵和相關資訊;

  • proxy_cache_key :設定快取使用的key,預設為訪問的完整URL,根據實際情況設定快取key;

  • proxy_cache_valid :為不同的響應狀態碼設定快取時間;如果是proxy_cache_valid 5s 則200、301、302響應將被快取;

proxy_cache_valid

proxy_cache_valid不是唯一設定快取時間的,還可以通過如下方式(優先順序從上到下):

以秒為單位的“X-Accel-Expires”響應頭來設定響應快取時間 如果沒有“X-Accel-Expires”,可以根據“Cache-Control”、“Expires”來設定響應快取時間 否則使用proxy_cache_valid設定的快取時間

如果響應頭包含Cache-Control:private/no-cache/no-store、Set-Cookie或者只有一個Vary響應頭且其值為*,則響應內容將不會被快取。可以使用proxy_ignore_headers來忽略這些響應頭。

proxy_cache_lock

當多個客戶端同時請求同一份內容時,如果開啟proxy_cache_lock(預設off)則只有一個請求被髮送至後端;其他請求將等待該內容返回;當第一個請求返回時,其他請求將從快取中獲取內容返回;當第一個請求超過了proxy_cache_lock_timeout超時時間(預設5s),則其他請求將同時請求到後端來獲取響應,且響應不會被快取;啟用proxy_cache_lock可以應對雪崩效應。

清理快取

有時候快取的內容是錯誤的,需要手工清理,可以使用ngx_cache_purge模組進行清理快取,如:
在這裡插入圖片描述

這樣只允許本地可以訪問,另外也可以配置password訪問

總結

快取雖然不是什麼很高深的的技術,但是快取是抗流量衝擊的銀彈,起到的作用舉足輕重 靜態檔案是可以快取很久的 快取是可以預熱的 如果業務場景允許,可以做開關,在遭受到流量衝擊的時候全部走快取,不迴流到後端伺服器 只快取200的響應, 後端響應錯誤不要返回200 快取的key設定需要合理,可以做個工具,快速刪除不正確的快取