CloudFront 快取策略實作思維與常見誤區(下)

CloudFront 快取策略實作思維與常見誤區(下)
圖文不符之 - 寧靜的午後,但寫這篇頭很痛完全不寧靜😂

本文為 CloudFront 系列第三篇,建議先閱讀以下文章了解基礎架構後再繼續。

CloudFront cache 錯頁面 Debug 流程(Rails 篇)
這篇文章從真實案例出發,帶你逐步排查 CloudFront 快取錯頁面的問題。解析 Rails 的預設 Header、CDN 設定與 DNS 模式,避免使用者畫面被快取錯誤、看到別人的資料。
CloudFront 快取設定詳解:Cache Key、TTL、Path Pattern 是什麼?(上)
CloudFront 的快取設定讓你一頭霧水?這篇用白話文解釋 Cache Key、TTL 和 Path Pattern,讓你一次掌握 CDN 的快取核心概念!

以下內容會幫助你理解 CloudFront 的快取策略與行為設定,特別是在使用「靜態子網域」架構下,如何避免快取錯頁面、快取不到東西、或誤信 AWS 推薦設定造成命中率極低的問題。

核心結論

使用靜態子網域架構時,請記住三個原則:

  1. 架構決定快取策略,必須先瞭解架構是什麼。換句話說,你的 DNS 走哪裡,就決定 CDN 會發揮什麼作用
  2. 大膽使用 CachingOptimized:DNS 已幫你過濾會進到 CDN 的 request,不必過度保守
  3. 忽略 AWS 預設建議:它不知道你的架構,所以會給最保守的選項

理解你的 DNS 架構

在提快取動態內容之前,我們先回到之前的文章:

CloudFront cache 錯頁面 Debug 流程(Rails 篇)
這篇文章從真實案例出發,帶你逐步排查 CloudFront 快取錯頁面的問題。解析 Rails 的預設 Header、CDN 設定與 DNS 模式,避免使用者畫面被快取錯誤、看到別人的資料。

裡面有提到:兩種常見的 CDN DNS 佈署模式,以下都以靜態子網域交給 CDN的模式說明。

靜態子網域交給 CDN 模式

舉例:

https://cdn.example.com/img/logo.pnghttps://static.example.com/img/logo.png

如果你的 DNS 只有 static.example.com → CloudFront,而 example.com 仍直指 EC2,那麼 CloudFront 只會處理 static 子網域的 request。

為什麼這很重要?

即使在 CloudFront 裡新增了 /api/* 行為,瀏覽器對 https://example.com/api 的請求 仍然不會經過 CloudFront,因為 Host header 不是 CDN host。因此,在設計快取策略前,請先確認「哪個 Host 會被解析到 CDN」,並檢查前端實際呼叫的 URL 是否符合預期。

換句話說:

如果是使用靜態子網域交給 CDN,就算不建立新的 behavior,只用 default 設置 cache policy 為 CachingOptimized 也很安全,因為只有靜態內容會套用。

補充:如果好奇公司網站 CDN 的架構是什麼,或者為什麼我們知道 API 請求不會經過 CDN,可以參考以下文章,在文章末有教你怎麼驗證 DNS 指向以及頁面是否被快取:

CloudFront cache 錯頁面 Debug 流程(Rails 篇)
這篇文章從真實案例出發,帶你逐步排查 CloudFront 快取錯頁面的問題。解析 Rails 的預設 Header、CDN 設定與 DNS 模式,避免使用者畫面被快取錯誤、看到別人的資料。

在確認架構後,接著讓我們看看實際設定時最容易掉入的陷阱:AWS Console 的預設建議。

AWS Console 推薦設定的陷阱

問題現象

當你進入 CloudFront 的 Default Behavior 設定時,AWS Console 會「貼心」地推薦你使用 UseOriginCacheHeaders 作為快取策略。

千萬別聽它的。

為什麼 AWS 這樣推薦?

  • AWS Console 無法判斷你到底要快取哪些路徑、Host 結構如何,而 default(*) 代表涵蓋所有路徑,所以他建議給你一個最保守」的選項,也就是 cachekey 設定最嚴謹的,因此很容易發生 cache miss,這是為了避免發生 cache 錯頁面的問題。
  • 如果 origin 設定為 S3,也適用於這個情境。

實際影響

項目 錯誤設定(AWS 建議) 正確設定(建議做法)
Cache Policy UseOriginCacheHeaders CachingOptimized
Cache 行為 頻繁 Miss Hit after warm-up
適用情境 AWS 無法預測 靜態子網域,架構已過濾

使用 UseOriginCacheHeaders 時,可以試著 curl 自己的靜態檔案(CSS/JS)看看,結果就會發現他一直顯示 Cache Miss。

curl -I <https://cdn.example.com/img/logo.png>
# 會看到以下結果,重複執行也是同樣結果!
# x-cache: Miss from cloudfront

靜態子網域的快取政策最佳設定

Default Behavior 直接使用 CachingOptimized 作為 cache policy

  • 這會積極快取所有經過的內容
  • 因為 DNS 架構已經幫你過濾了,不用擔心快取到動態頁面

簡化 Path Pattern 設計

  • 在靜態子網域架構下,你可能根本不需要額外建立 /assets/*/images/* 的 Behavior,因為所有請求都已經走 Default Behavior。上面所述路徑也包含在內。

驗證設定效果

# 測試任一靜態檔案
curl -I <https://cdn.example.com/img/logo.png>

# 第一次:Miss from cloudfront
# 第二次:Hit from cloudfront ← 這就對了!

這篇其實是記錄我第一次實作 CloudFront 時不太懂的地方。如果沒有這些概念,其實進到設定的時候會搞不懂怎麼設定比較好。又或者設定之後只能確認 Cloudfront 可以動,但事實上設定有問題卻沒有發現。這些內容實際去了解之後,才發現每個設定都是個學問啊…。

也希望這篇能幫到跟我一樣第一次接觸 CloudFront 的人,至少少踩一些 AWS 預設值的坑。😆😆