首頁 >後端開發 >php教程 >談談關於CDN緩存

談談關於CDN緩存

一个新手
一个新手原創
2017-09-07 10:24:416910瀏覽

一、CDN是什麼?

談到CDN的作用,可以用8年買火車票的經歷來形像比喻:

#8年前,還沒有火車票代售點一說,12306.cn更是無從說起。那時候火車票還只能在火車站的售票大廳購買,而我所住的小縣城並不通火車,火車票都要去市裡的火車站購買,而從縣城到市裡,來回就是4個小時車程,簡直就是浪費生命。後來就好了,小縣城裡出現了火車票代售點,可以直接在代售點購買火車,方便了不少,全市人民再也不用在一個點苦逼的排隊買票了。

CDN就可以理解為分佈在每個縣城的火車票代售點,用戶在瀏覽網站的時候,CDN會選擇一個離用戶最近的CDN邊緣節點來響應用戶的請求,這樣海南移動用戶的請求就不會千里迢迢跑到北京電信機房的伺服器(假設源站部署在北京電信機房)上了。

CDN的優勢很明顯:(1)CDN節點解決了跨運營商和跨地域訪問的問題,訪問延時大大降低;(2)大部分請求在CDN邊緣節點完成,CDN起到了分流作用,減輕了源站的負載。

二、快取是什麼?

這裡不深究CDN背後高大上的架構,也不討論CDN如何做到全域流量調度策略,本文著重討論在有了CDN後,資料是如何被快取的。快取是一個到處都存在的用空間換時間的例子。透過使用多餘的空間,我們能夠獲取更快的速度。
首先,看看沒有網站沒有接入CDN時,用戶瀏覽器與伺服器是如何互動的:
談談關於CDN緩存
用戶在瀏覽網站的時候,瀏覽器能夠在本地保存網站中的圖片或其他文件的副本,這樣使用者再次造訪該網站的時候,瀏覽器就不用再下載全部的文件,減少了下載量意味著提高了頁面載入的速度。
如果中間加上一層CDN,那麼使用者瀏覽器與伺服器的互動如下:
談談關於CDN緩存
客戶端瀏覽器先檢查是否有本機快取是否過期,如果過期,則向CDN邊緣節點發起請求,CDN邊緣節點會偵測使用者請求資料的快取是否過期,如果沒有過期,則直接回應使用者請求,此時一個完成http請求結束;如果資料已經過期,那麼CDN還需要向來源站發出回源請求(back to the source request),來拉取最新的資料。 CDN的典型拓撲圖如下:
談談關於CDN緩存
可以看到,在存在CDN的場景下,資料經歷了客戶端(瀏覽器)快取和CDN邊緣節點快取兩個階段,以下分別對這兩個階段的快取進行詳細的剖析
二、客戶端(瀏覽器)快取

  • #客戶端快取的缺點

客戶端快取減少了的伺服器請求,避免了檔案重複加載,顯著地提升了用戶地方。但當網站發生了更新的時候(如替換了css、js以及圖片文件),瀏覽器本地仍保存著舊版本的文件,從而導致無法預料後果。

曾幾何時,一個頁面加載出來,頁面各元素位置亂飄,按鈕點擊失效,前端GG都會習慣性地問一句:“緩存清了沒?”,然後Ctrl+F5       ,Everything is OK。但有些時候,如果我們是簡單地在瀏覽器地址欄中敲一個回車,或者是僅按F5刷新,問題依然沒有解決,你可知道這三種不同的操作方式,決定瀏覽器不同的刷新緩存策略?

瀏覽器如何來決定使用本機檔案還是使用伺服器上的新檔案?下面來介紹幾種判斷的方法。

  • 瀏覽器快取策略

Expires

Expires:Sat, 24 Jan 2015 20:30:54 GMT
談談關於CDN緩存
如果http回應封包中設定了Expires,在Expires過期之前,我們就避免了和伺服器之間的連線。此時,瀏覽器不需要想瀏覽器發出請求,只需要自己判斷手中的資料是否過期就可以了,完全不需要增加伺服器的負擔。
Cache-control: max-age
談談關於CDN緩存
Expires的方法很好,但是我們每次都要算一個精確的時間。 max-age 標籤可以讓我們更容易的處理過期時間。我們只要說,這份資料你只能用一個禮拜就可以了。

Max-age 使用秒來計量,如:
Cache-Control:max-age=645672
指定頁面645672秒(7.47天)後過期。
Last-Modified
伺服器為了通知瀏覽器目前檔案的版本,會傳送一個上次修改時間的標籤,例如:
Last-Modified:Tue, 06 Jan 2015 08 :26:32 GMT
談談關於CDN緩存
這樣瀏覽器就知道他收到的這個文件創建時間,在後續的請求中,瀏覽器會按照下面的規則進行驗證:
1.  瀏覽器:Hey,我需要jquery.min.js這個文件,如果是在Tue, 06 Jan 2015 08:26:32 GMT 之後修改過的,請寄給我。
2.  伺服器:(檢查檔案的修改時間)
3.  伺服器:Hey,這個檔案在那個時間之後沒有被修改過,你已經有最新的版本了。
4.  瀏覽器:太好了,那我就顯示給使用者了。
在這種情況下,伺服器僅僅回傳了一個304的回應頭,減少了回應的資料量,提高了回應的速度。關於304回應,請參考:
http://www.cnblogs.com/ziyunfei/archive/2012/11/17/2772729.html
下圖是按F5刷新頁面後,頁面回到304回應頭。
談談關於CDN緩存
ETag
通常情況下,透過修改時間來比較檔案是可行的。但是在一些特殊情況,例如伺服器的時鐘發生了錯誤,伺服器時鐘進行修改,夏時制DST到來後伺服器時間沒有及時更新,這些都會引起透過修改時間比較檔案版本的問題。

ETag可以用來解決這種問題。 ETag是一個檔案的唯一標誌符。就像一個哈希或指紋,每個檔案都有一個單獨的標誌,只要這個檔案改變了,這個標誌就會改變。

伺服器傳回ETag標籤:
ETag:」39001d-1762a-50bf790757e00”
談談關於CDN緩存
接下來的存取順序如下所示:
- 瀏覽器:Hey,我需要jquery.min.js這個文件,有沒有不匹配」39001d-1762a-50bf790757e00」這個串的
- 伺服器:(檢查ETag…)
- 伺服器:Hey,我這裡的版本也是”39001d-1762a-50bf790757e00”,你已經是最新的版本了
- 瀏覽器:好,那就可以使用本機快取了
如 Last-modified 一樣,ETag 解決了檔案版本比較的問題。只不過 ETag 的等級比 Last-Modified 高一些。
額外的標籤
快取標籤永遠不會停止運作,但是有時候我們需要對已經快取的內容進行一些控制。
l  Cache-control: public 表示快取的版本可以被代理伺服器或其他中間伺服器辨識。
l  Cache-control: private 表示這個檔案對不同的使用者是不同的。只有使用者自己的瀏覽器能夠進行緩存,公共的代理伺服器不允許快取。
l  Cache-control: no-cache 表示檔案的內容不應被快取。這在搜尋或翻頁結果中非常有用,因為同樣的URL,對應的內容會改變。
談談關於CDN緩存
# - 瀏覽器快取刷新

  • 在地址列中輸入網址後按回車或點擊轉到按鈕
    瀏覽器以最少的請求來獲取網頁的數據,瀏覽器會對所有沒有過期的內容直接使用本地緩存,從而減少了對瀏覽器的請求。所以,Expires,max-age標記只對這種方式有效。

  • 按F5或瀏覽器刷新按鈕
    瀏覽器會在請求中附加必要的快取協商,但不允許瀏覽器直接使用本地緩存,它能夠讓Last-Modified 、ETag發揮效果,但對Expires無效。

  • 按Ctrl+F5或按Ctrl並點擊刷新按鈕
    這種方式就是強制刷新,總是會發起一個全新的請求,不使用任何快取。

  • CDN快取

瀏覽器本機快取失效後,瀏覽器會向CDN邊緣節點發起請求。類似瀏覽器緩存,CDN邊緣節點也存在著一套快取機制。

  • CDN快取的缺點

CDN的分流作用不僅減少了使用者的存取延時,也減少的來源站的負載。但其缺點也很明顯:當網站更新時,如果CDN節點上資料沒有及時更新,即便用戶再瀏覽器使用Ctrl +F5的方式使瀏覽器端的快取失效,也會因為CDN邊緣節點沒有同步最新資料而導致用戶存取異常。

  • CDN快取策略

CDN邊緣節點快取策略因服務商不同而不同,但一般都會遵循http標準協議,透過http回應頭中的Cache-control: max-age的欄位來設定CDN邊緣節點數據緩存時間。

當客戶端向CDN節點請求資料時,CDN節點會判斷快取資料是否過期,若快取資料並沒有過期,直接將快取資料傳回給客戶端;否則,CDN節點就會向來源站發出回源請求,從來源站拉取最新數據,更新本地緩存,並將最新數據傳回給客戶端。

CDN服務商一般會提供基於檔案後綴、目錄多個維度來指定CDN快取時間,為使用者提供更精細的快取管理。

CDN快取時間會對「回源率」產生直接的影響。若CDN快取時間較短,CDN邊緣節點上的資料會經常失效,導致頻繁回源,增加了源站的負載,同時也增大的存取延遲;若CDN快取時間太長,會帶來資料更新時間慢的問題。開發者需要增對特定的業務,來做特定的資料快取時間管理。

  • CDN快取刷新

CDN邊緣節點對開發者是透明的,相較於瀏覽器Ctrl+F5的強制刷新來使瀏覽器本地快取失效,開發者可以透過CDN服務商提供的「刷新快取」介面來達到清理CDN邊緣節點快取的目的。這樣開發者在更新資料後,可以使用「刷新快取」功能來強制CDN節點上的資料快取過期,確保客戶端在存取時,拉取到最新的資料。

以上是談談關於CDN緩存的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn