Web緩存是指一個Web資源(如html頁面,圖片,js,數據等)存在於Web服務器和客戶端(瀏覽器)之間的副本。緩存會根據進來的請求保存輸出內容的副本;當下一個請求來到的時候,若是是相同的URL,緩存會根據緩存機制決定是直接使用副本響應訪問請求,仍是向源服務器再次發送請求。比較常見的就是瀏覽器會緩存訪問過網站的網頁,當再次訪問這個URL地址的時候,若是網頁沒有更新,就不會再次下載網頁,而是直接使用本地緩存的網頁。只有當網站明確標識資源已經更新,瀏覽器纔會再次下載網頁html
Web應用,特別是SNS類型的應用,每每關係比較複雜,數據庫表繁多,若是頻繁進行數據庫查詢,很容易致使數據庫不堪重荷。爲了提供查詢的性能,會將查詢後的數據放到內存中進行緩存,下次查詢時,直接從內存緩存直接返回,提供響應效率。好比經常使用的緩存方案有memcached等。web
代理服務器緩存
代理服務器是瀏覽器和源服務器之間的中間服務器,瀏覽器先向這個中間服務器發起Web請求,通過處理後(好比權限驗證,緩存匹配等),再將請求轉發到源服務器。代理服務器緩存的運做原理跟瀏覽器的運做原理差很少,只是規模更大。能夠把它理解爲一個共享緩存,不僅爲一個用戶服務,通常爲大量用戶提供服務,所以在減小相應時間和帶寬使用方面頗有效,同一個副本會被重用屢次。常見代理服務器緩存解決方案有Squid等數據庫
CDN
緩存CDN
(Content delivery networks)緩存,也叫網關緩存、反向代理緩存。CDN
緩存通常是由網站管理員本身部署,爲了讓他們的網站更容易擴展並得到更好的性能。瀏覽器先向CDN
網關發起Web請求,網關服務器後面對應着一臺或多臺負載均衡源服務器,會根據它們的負載請求,動態將請求轉發到合適的源服務器上。雖然這種架構負載均衡源服務器之間的緩存無法共享,但卻擁有更好的處擴展性。瀏覽器
瀏覽器緩存根據一套與服務器約定的規則進行工做,在同一個會話過程當中會檢查一次並肯定緩存的副本足夠新。若是你瀏覽過程當中,好比前進或後退,訪問到同一個圖片,這些圖片能夠從瀏覽器緩存中調出而即時顯現。緩存
應用層緩存指的是從代碼層面上,經過代碼邏輯和緩存策略,實現對數據,頁面,圖片等資源的緩存,能夠根據實際狀況選擇將數據存在文件系統或者內存中,減小數據庫查詢或者讀寫瓶頸,提升響應效率。服務器
全部的緩存都是基於一套規則來幫助他們決定何時使用緩存中的副本提供服務(假設有副本可用的狀況下,未被銷燬回收或者未被刪除修改)。這些規則有的在協議中有定義(如HTTP協議1.0和2.0),有的則是由緩存的管理員設置(如DBA、瀏覽器的用戶、代理服務器管理員或者應用開發者)架構
對於瀏覽器端的緩存來說,這些規則是在HTTP協議頭和HTML頁面的Meta標籤中定義的。他們分別重新鮮度和校驗值兩個維度來規定瀏覽器是否能夠直接使用緩存中的副本,仍是須要去源服務器獲取更新的版本。app
新鮮度(過時機制):也就是緩存副本有效期。一個緩存副本必須知足如下條件,瀏覽器會認爲它是有效的,足夠新的:負載均衡
含有完整的過時時間控制頭信息(HTTP
協議報頭Cache-Control
與Expires
),而且仍在有效期內;memcached
若是已經超過有效期,發起請求到服務器驗證Etag,若是沒有更新,仍是使用瀏覽器緩存
知足以上兩個狀況的一種,瀏覽器會直接從緩存中獲取副本並渲染。
校驗值(驗證機制):
Cache-Control
與Expires
的做用一致,都是指明當前資源的有效期,控制瀏覽器是否直接從瀏覽器緩存取數據仍是從新發請求到服務器取數據。只不過Cache-Control
的選擇更多,設置更細緻,若是同時設置的話,其優先級高於Expires
。
服務器返回資源的時候有時在控制頭信息帶上這個資源的實體標籤Etag
(Entity Tag),它能夠用來做爲瀏覽器再次請求過程的校驗標識。如過發現校驗標識不匹配,說明資源已經被修改或過時,瀏覽器需求從新獲取資源內容。
若是檢測到本地的緩存仍是有效的時間範圍內,瀏覽器直接使用本地副本,不會發送任何請求。二者一塊兒使用時,Cache-Control/Expires
的優先級要高於Last-Modified/ETag
。即當本地副本根據Cache-Control/Expires
發現還在有效期內時,則不會再次發送請求去服務器詢問修改時間(Last-Modified)或實體標識(Etag)了。
通常狀況下,使用Cache-Control/Expires
會配合Last-Modified/ETag
一塊兒使用,由於即便服務器設置緩存時間, 當用戶點擊「刷新」按鈕時,瀏覽器會忽略緩存繼續向服務器發送請求,這時Last-Modified/ETag
將可以很好利用304,從而減小響應開銷。
Last-Modified/ETag
你可能會以爲使用Last-Modified
已經足以讓瀏覽器知道本地的緩存副本是否足夠新,爲何還須要Etag(實體標識)呢?HTTP1.1中Etag的出現主要是爲了解決幾個Last-Modified
比較難解決的問題:Last-Modified
標註的最後修改只能精確到秒級,若是某些文件在1秒鐘之內,被修改屢次的話,它將不能準確標註文件的新鮮度
若是某些文件會被按期生成,當有時內容並無任何變化,但Last-Modified
卻改變了,致使文件無法使用緩存
有可能存在服務器沒有準確獲取文件修改時間,或者與代理服務器時間不一致等情形Etag
是服務器自動生成或者由開發者生成的對應資源在服務器端的惟一標識符,可以更加準確的控制緩存。Last-Modified
與Etag
是能夠一塊兒使用的,服務器會優先驗證Etag
,一致的狀況下,纔會繼續比對Last-Modified
,最後才決定是否返回304
用戶在使用瀏覽器的時候,會有各類操做,好比輸入地址後回車,按F5刷新等,這些行爲會對緩存有什麼影響呢?
經過上表咱們能夠看到,當用戶在按F5進行刷新的時候,會忽略Cache-Control/Expires
的設置,會再次發送請求去服務器請求,而Last-Modified/ETag
仍是有效的,服務器會根據狀況判斷返回304仍是200;而當用戶使用Ctrl+F5進行強制刷新的時候,只是全部的緩存機制都將失效,從新從服務器拉去資源。