緩存在web環境各個環節都有實現,有CPU緩存、文件緩存、程序的Opcode緩存(APC,eAccelerator)、內存緩存(Memcached,Redis)、代理服務器(Nginx,Squid)、數據庫的查詢緩存、基于HTTP的客戶端緩存。其中HTTP緩存是離用戶最近的緩存,訪問最快,合理使用可以加快數據加載速度、減少服務器的開銷。
HTTP緩存通過設置一些頭加以控制,有一部分是控制要不要緩存、怎么緩存以及緩存多久的,還有一部分是決定緩存過期以后怎么處理的。下面只列出最主要的:
緩存控制
Cache-Control
public:公共,可以被客戶端和代理服務器(如Nginx、Squid)緩存
private:私有,只能被當前客戶端緩存
no-store:不緩存,客戶端不維護緩存
no-cache:并不是不緩存,但是每次都會請求服務器,可以配合ETag和Last-Modified來避免響應重復的內容,適用于需要顯示最新內容的場景
max-stale:客戶端可以設置它來使用已經過期的緩存,單位為秒,這個時間是已經過期了多少秒的意思
must-revalidate:因為客戶端可以設置max-stale來使用已經過期的緩存,服務器可以設置它來強制客戶端不允許使用過期的緩存,必須重新請求服務器
Pragma:相比Cache-Control,它是不支持響應頭的,通常是為了向后兼容HTTP/1.0
緩存時間
max-age:距離請求發起的時間的秒數,Cache-Control指令之一
Expires:過期時間(GMT格式),和max-age類似,但是Expires受客戶端時間影響,是HTTP/1.0的標準,max-age是它的改良版,優先級為:max-age -> Expires
緩存校驗(緩存過期后通過比較來檢查是否繼續使用)
Last-Modified:服務端在響應頭里面設置此項來告知客戶端資源的修改時間(GMT格式),客戶端會在下次請求時自動加上If-Modified-Since: <last_modified_value>,服務端以此來比對緩存是否有更新
ETag(Entity Tags):依賴Last-Modified來檢查緩存有缺陷,比如文件的修改時間變了但是內容沒有變,又比如它只能精確到秒,而ETag是比對內容,可以理解為md5值,服務端響應ETag后客戶端會在下次請求時自動帶上If-None-Match: <etag_value>。ETag比Last-Modified開銷大,如果可以用Last-Modified盡量用Last-Modified
注意private的應用場景,比如個人中心的url是/userinfo.php,所有人的url都是相同的,這個時候如果用了public走了代理緩存,會導致所有人共享一個緩存,所以這種時候需要使用private。
實例
緩存一分鐘,一分鐘內直接讀取本地緩存,一分鐘后重新請求服務器:
Cache-Control: public, max-age=60, must-revalidate
上面這種方式一旦緩存過期就會重新請求服務器返回最新的內容,如果內容并沒有變化,那不是白傳了?有沒有辦法在緩存過期以后判斷一下如果內容沒有改變則繼續用本地的緩存呢?很簡單!ETag可以幫到你,有效期內直接讀取本地緩存,過期后跟服務器比對ETag,相同則服務器會返回304表示緩存還可以繼續用,而不返回實際內容,節約了時間和帶寬。
HTTP緩存通過設置一些頭加以控制,有一部分是控制要不要緩存、怎么緩存以及緩存多久的,還有一部分是決定緩存過期以后怎么處理的。下面只列出最主要的:
緩存控制
Cache-Control
public:公共,可以被客戶端和代理服務器(如Nginx、Squid)緩存
private:私有,只能被當前客戶端緩存
no-store:不緩存,客戶端不維護緩存
no-cache:并不是不緩存,但是每次都會請求服務器,可以配合ETag和Last-Modified來避免響應重復的內容,適用于需要顯示最新內容的場景
max-stale:客戶端可以設置它來使用已經過期的緩存,單位為秒,這個時間是已經過期了多少秒的意思
must-revalidate:因為客戶端可以設置max-stale來使用已經過期的緩存,服務器可以設置它來強制客戶端不允許使用過期的緩存,必須重新請求服務器
Pragma:相比Cache-Control,它是不支持響應頭的,通常是為了向后兼容HTTP/1.0
緩存時間
max-age:距離請求發起的時間的秒數,Cache-Control指令之一
Expires:過期時間(GMT格式),和max-age類似,但是Expires受客戶端時間影響,是HTTP/1.0的標準,max-age是它的改良版,優先級為:max-age -> Expires
緩存校驗(緩存過期后通過比較來檢查是否繼續使用)
Last-Modified:服務端在響應頭里面設置此項來告知客戶端資源的修改時間(GMT格式),客戶端會在下次請求時自動加上If-Modified-Since: <last_modified_value>,服務端以此來比對緩存是否有更新
ETag(Entity Tags):依賴Last-Modified來檢查緩存有缺陷,比如文件的修改時間變了但是內容沒有變,又比如它只能精確到秒,而ETag是比對內容,可以理解為md5值,服務端響應ETag后客戶端會在下次請求時自動帶上If-None-Match: <etag_value>。ETag比Last-Modified開銷大,如果可以用Last-Modified盡量用Last-Modified
注意private的應用場景,比如個人中心的url是/userinfo.php,所有人的url都是相同的,這個時候如果用了public走了代理緩存,會導致所有人共享一個緩存,所以這種時候需要使用private。
實例
緩存一分鐘,一分鐘內直接讀取本地緩存,一分鐘后重新請求服務器:
Cache-Control: public, max-age=60, must-revalidate
上面這種方式一旦緩存過期就會重新請求服務器返回最新的內容,如果內容并沒有變化,那不是白傳了?有沒有辦法在緩存過期以后判斷一下如果內容沒有改變則繼續用本地的緩存呢?很簡單!ETag可以幫到你,有效期內直接讀取本地緩存,過期后跟服務器比對ETag,相同則服務器會返回304表示緩存還可以繼續用,而不返回實際內容,節約了時間和帶寬。
我們憑借多年的網站建設經驗,堅持以"幫助中小企業實現網絡營銷化"為宗旨,累計為4000多家客戶提供品質建站服務,得到了客戶的一致好評。如果您有網站建設、網站改版、域名注冊、主機空間、手機網站建設、網站備案等方面的需求...
請立即點擊咨詢我們或撥打咨詢熱線: 13812912584 / 18013771099,我們會詳細為你一一解答你心中的疑難。項目經理在線
請立即點擊咨詢我們或撥打咨詢熱線: 13812912584 / 18013771099,我們會詳細為你一一解答你心中的疑難。項目經理在線