CDN緩存策略
CDN(Content Delivery network,內容分發網絡),通過GSLB技術使得用戶能訪問到最近物理機房的文件,以節省網絡時間,也就是說一份文件可能會在全國乃至全球的多個服務器存在,這就涉及到一個文件分發的問題,目前通常的CDN都是采取回源策略來同步文件,即每個cdn域名關聯了一些源服務器,發布文件只要發布到源服務器即可,cdn會根據策略從源服務器拉取文件,以保證用戶能盡早訪問到最新的文件內容。
那么cdn何時會去源服務器取內容呢?事實上,這個策略和瀏覽器緩存非常類似,我們知道,http 1.1通過cache-control的max-age頭可以告知文件在瀏覽器的緩存時間,在max-age指定的時間內,瀏覽器會直接使用本地緩存,而不會請求服務器,cdn采取了類似的機制,你只要把cdn節點看成瀏覽器,源服務器看成瀏覽器需要請求的服務器即可,此時,源服務器的max-age頭決定了資源在cdn節點本地緩存的時間,有一點差別的是,cdn規定了一個自定義協議,s-maxage,若源站該header存在,會優先使用該header作為緩存時間:
Cache-Control:max-age=0, s-maxage=86400
舉個栗子解釋下cdn緩存策略:
為了避免干擾,我們假設例子中說的cdn只有你一個人在訪問。
源站的max-age設定了緩存時間為3600秒,即一小時,cdn的max-age設定了緩存時間為315360000秒,即10年,那么用戶首次訪問該cdn的文件a.js?v=1時,cdn節點發現本機沒有該文件的緩存,會去源服務器取,接下來該文件會在cdn節點緩存3600秒,cdn節點帶上自己的max-age頭(315360000)返回到瀏覽器,接下來用戶之后10年內訪問同一個a.js?v=1不會再發請求(非刷新情況下,且用戶側緩存假設不清除)。
若用戶在一小時之內刷新a.js?v=1,意味着該請求會進到cdn服務器,此時服務器發現該url的緩存還沒過期(在3600秒內),不會去源站請求,直接返回服務器內容,根據請求header的last-modified(ctrl+f5不帶,f5和回車帶)決定是吐出304還是200。
若用戶在一小時之后刷新a.js?v=1,意味着該請求會進到cdn服務器,此時服務器發現該url的緩存已經超過了3600秒,於是會去源站請求一次,源站會根據請求header的last-modified(ctrl+f5不帶,f5和回車帶)決定是否吐出304還是200,並把源站的響應直接吐出到瀏覽器。
對於這個例子,用戶側最壞的情況是10年不請求新版的js,那么怎么解決這個問題,想必大家也知道了,就是加版本號(比如時間戳,可參考此文),因為無論是瀏覽器緩存還是cdn的緩存,其緩存的key都是get請求,而不只是文件名,因此若a.js變成a.js?v=2,無論是瀏覽器還是cdn,都會去上一級網絡拿取更新的資源。
對於不適合加版本號的頁面,比如html文檔,此時源站的max-age就要設短一點了,比如設置成1小時,那么再壞的情況下,cdn也會在1小時候回源拿取新的內容,如果想快點生效,需要使用cdn的緩存清理API或工具。
另外可以通過age頭查看該資源在當前cdn節點已緩存了多久:
Age: 1921
X-Cache: HIT TCP_MEM_HIT dirn:5:277366080
比如這個例子說明已緩存1921秒。
CDN緩存和瀏覽器緩存之間的關系
回源和回源比
- 什么是回源?
網上查了下資料,回源大致是指瀏覽器在發送請求報文時,響應該請求報文的是源站點的服務器,而不是各節點上的緩存服務器,那么這個過程相對於通過各節點上的緩存服務器來響應的話就稱作為回源。回源的請求或流量太多的話,有可能會讓源站點的服務器承載着過大的訪問壓力,進而影響服務的正常訪問。
- 如何計算回源比?
其實回源比和緩存的命中率正好相反,回源比高,說明緩存系統的緩存命中率低。回源比分為回源請求數比例和回源流量比例兩種。
回源請求數比例:收集所有邊緣節點上的請求記錄,沒有緩存或緩存過期的請求以及不可緩存的請求均被作為回源請求,發往源站點服務器響應。其他的請求則由緩存系統直接使用緩存響應。其計算公式為:回源請求數/(回源請求數+用戶發送的請求數)
。
回源流量比:即用戶所產生的流量當中,有多少流量是直接有源站點服務器響應的,其計算公式為:回源流量/(回源流量+用戶請求訪問的流量)