CDN 工作原理圖解:快取命中、回源機制與智慧路由完整解析

用流程圖解拆解 CDN 請求路徑:從 DNS 解析、邊緣節點快取判斷、回源機制到智慧路由與負載均衡,幫你看懂每一步發生了什麼事。

CDN快取命中Cache HitCache Miss回源機制邊緣運算Edge Node智慧路由負載均衡AnycastCloudflare網站加速運作原理HTTP Header教學

CDN 最難理解的地方,不是名詞,而是整條請求路徑到底怎麼跑。當你知道使用者、邊緣節點和來源站之間的互動,之後看快取命中率、排錯或調規則都會順很多。

你如果希望這篇不只是看完「大概知道」,而是真的能拿來安排自己的部署或排錯順序,那就把每一步都對照你現在的環境去看,效果會差很多。

你會學到什麼

  • 把 CDN 工作流程用一條線串起來,從 DNS 查詢到內容回傳。
  • 理解 Cache Hit 與 Miss 的差別,以及不同快取狀態代表什麼。
  • 搞懂回源機制的細節,包括條件式回源和回源 Header。
  • 知道智慧路由和負載均衡怎麼讓 CDN 更穩定。
  • 之後遇到資源更新不即時時,更知道從哪裡排查。

什麼情況最適合先看這篇

  • 想讓網站更快、更穩,並把 DNS、SSL、快取一起整理好的站長
  • 你開了 CDN 但遇到「改了東西卻沒看到更新」的問題
  • 你想了解 CDN 快取狀態(HIT、MISS、EXPIRED)各代表什麼
  • 你希望做完後不只是功能可用,連驗證與風險也一起想進去

開始前先確認

  • 先有基本 DNS 和網站請求概念,如果不熟可以先看 DNS 基礎教學
  • 手邊最好有一個實際網站案例可以對照。
  • 如果你對 CDN 基本概念還不清楚,建議先看 CDN 基礎教學
  • 如果你常碰 Cloudflare 快取問題,這篇特別值得先看。

先提醒你一件事

CDN、DNS、Proxy 與 SSL 是互相連動的,不要一次開很多開關卻沒有逐步驗證。

詳細教學與操作步驟

完整請求流程:從訪客到內容回傳

當一個訪客在瀏覽器輸入你的網址,到頁面顯示出來,中間經過了這些步驟:

讓我們一步一步拆解。

第一步:DNS 解析與 Anycast 路由

訪客輸入 yoursite.com,瀏覽器先問 DNS:「這個網域的 IP 是什麼?」

如果你用 Cloudflare,DNS 回傳的 IP 不是你原站的 IP,而是 Cloudflare 的 Anycast IP。Anycast 是一種特殊的路由技術:同一個 IP 位址,在全球很多地方都有伺服器在「回應」。

# 你可以用 dig 查看 DNS 解析結果
dig yoursite.com

# 回傳的 IP 是 Cloudflare 的,不是你原站的
;; ANSWER SECTION:
yoursite.com.    300    IN    A    104.21.xx.xx

Anycast 的好處

  • 訪客的請求會自動被路由到「網路距離最近」的資料中心
  • 不需要你設定任何 GeoDNS,Anycast 在網路層就搞定了
  • 如果某個資料中心故障,流量自動轉到下一個最近的,你什麼都不用做

注意:Anycast 的「最近」是指網路跳數最少,不一定是地理距離最近。台灣的訪客可能被路由到台北、東京或香港的節點,取決於當時的網路狀態。

第二步:到達邊緣節點

請求到達邊緣節點後,CDN 要做一個關鍵判斷:「這個請求的資源,我手上有沒有?」

這個判斷的依據是:

  • 請求的 URL 路徑
  • 請求的 Host Header
  • 快取的 TTL 有沒有過期
  • 是否有被 Page Rule 或快取規則排除

第三步:快取命中(Cache Hit)

如果邊緣節點有這個資源的快取,而且還沒過期,就直接回傳給訪客。這是最快的情況,延遲通常在 5-15ms。

你可以在 Chrome DevTools 的 Network 面板看到回應的 Header:

cf-cache-status: HIT
age: 3600

age: 3600 表示這份快取已經存在邊緣節點上 3600 秒(1 小時)了。

影響快取命中率的因素

  1. TTL 設定:TTL 越長,快取命中率越高。但你要平衡內容即時性。
  2. 流量分布:如果你的訪客分散在很多國家,每個邊緣節點的快取都要獨立建立,命中率會比流量集中的情況低。
  3. 資源 URL 的一致性/image.jpg/image.jpg?v=1/Image.jpg 對 CDN 來說是三個不同的資源。URL 不一致會嚴重降低命中率。

第四步:快取未命中(Cache Miss)與回源

如果邊緣節點沒有快取,或者快取已過期,就要「回源」——向你的原始伺服器要資源。

完整回源 vs 條件式回源

不是每次回源都需要傳完整內容。如果原站支援 ETagLast-Modified Header,邊緣節點可以用「條件式請求」:

# 邊緣節點發出的條件式請求
GET /style.css HTTP/1.1
If-None-Match: "abc123def456"

如果原站的檔案沒變,就回 304 Not Modified,不傳內容,只傳 Header。這省下了大量的回源頻寬。

如果原站的檔案變了,就回 200 OK 加上新的內容和新的 ETag。

回源失敗怎麼辦?

如果回源時原站掛了(5xx 錯誤或連不上),不同的 CDN 有不同的處理方式:

  • Cloudflare 預設:回傳 Cloudflare 的錯誤頁面(502/504)
  • Always Online(Cloudflare 功能):提供 Internet Archive 的快取版本
  • 自訂設定:你可以設定「回源失敗時,提供過期的快取內容」,這在 Cloudflare 的 Cache Rules 裡可以設定

對於重要的網站,建議開啟「Serve Stale」功能:

Cache-Control: public, max-age=3600, stale-if-error=86400

這行的意思是:「快取 1 小時。如果回源失敗,可以繼續用過期的快取,最多 24 小時。」這能讓你的網站在原站短暫故障時仍然可用。

第五步:快取存儲與回傳

邊緣節點從原站拿到內容後,會做兩件事:

  1. 存一份在自己的快取裡
  2. 回傳給訪客

之後同一個邊緣節點收到相同資源的請求,就直接從快取回傳,不需要再回源。

智慧路由(Smart Routing)

基礎的 CDN 只是「就近取件」,但現代 CDN 還有智慧路由的能力。

什麼是智慧路由?

網際網路不是一條直線,從 A 到 B 可能有很多條路徑。有些路徑塞車(壅塞)、有些路徑繞路(跳數多)、有些路徑斷了(故障)。

智慧路由就是 CDN 根據即時的網路狀態,選一條最快的路徑來傳送你的請求和內容。

Cloudflare Argo Smart Routing

Cloudflare 的 Argo Smart Routing 是付費功能,原理是:

  1. Cloudflare 持續監測自己全球網路中,每條路徑的延遲和封包遺失率
  2. 當你的請求需要回源時,Argo 不走公開的網際網路,而是走 Cloudflare 自己的私有骨幹網路
  3. 這條私有路徑通常比公開網路更快、更穩定

Cloudflare 的數據顯示,Argo 平均能減少 30% 的回源延遲。對於原站在海外但主要訪客在亞洲的網站來說,效果特別明顯。

不過免費方案沒有 Argo。如果你的預算有限,把原站放在離主要訪客近的地方(例如用侃瑞科技的 VPS 方案),效果可能更直接。

負載均衡(Load Balancing)

當你的網站流量大到一台伺服器撐不住,或者你需要高可用(High Availability),就需要負載均衡。

CDN 層級的負載均衡

CDN 的邊緣節點本身就是一種負載均衡:流量被分散到全球各地的節點,不會全部壓在你的原站上。

原站層級的負載均衡

如果你有多台原站(例如一台在台灣、一台在美國),CDN 可以根據以下條件選擇回源到哪一台:

  • 地理位置:亞洲的邊緣節點回源到台灣的原站,美洲的回源到美國的原站
  • 健康檢查:定期 ping 每台原站,如果某台掛了就不再回源到它
  • 權重:例如 70% 的流量回源到主機 A,30% 回源到主機 B

Cloudflare 的 Load Balancing 是付費功能,但對於多數中小型網站來說,一台好的 VPS 加上 CDN 快取就夠用了。

邊緣運算(Edge Computing)

這是 CDN 技術的新方向。傳統 CDN 只能快取靜態內容,邊緣運算讓你可以在邊緣節點「跑程式」。

Cloudflare Workers

Cloudflare Workers 讓你在邊緣節點執行 JavaScript,常見用途:

  • A/B 測試:在邊緣節點決定顯示版本 A 還是版本 B,不需要回源
  • URL 重寫:在邊緣節點就把 /old-page 轉到 /new-page
  • 請求過濾:根據自訂邏輯(國家、裝置、Cookie)決定要不要允許請求
  • API Gateway:在邊緣做速率限制、驗證、回應快取
// Cloudflare Worker 範例:根據國家重導向
addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const country = request.cf.country
  
  if (country === 'TW') {
    // 台灣訪客,導向中文版
    return Response.redirect('https://tw.example.com' + new URL(request.url).pathname, 302)
  }
  
  // 其他國家,正常回源
  return fetch(request)
}

HTTP Header 與快取控制的完整對照

理解這些 Header,你就能讀懂 CDN 的行為:

請求端(瀏覽器 → CDN)的重要 Header

Header用途範例
Cache-Control: no-cache有快取也要回源驗證瀏覽器按 F5 重新整理
Cache-Control: no-store完全不要快取敏感頁面
If-None-Match條件式請求,帶 ETag節省頻寬
If-Modified-Since條件式請求,帶時間節省頻寬

回應端(CDN → 瀏覽器)的重要 Header

Header用途範例
Cache-Control: public, max-age=86400可以被任何快取存 1 天靜態資源
Cache-Control: private, no-cache只能瀏覽器存,每次要驗證含登入狀態的頁面
ETag: "abc123"資源的指紋條件式回源用
Vary: Accept-Encoding不同編碼各存一份快取gzip 和 br 各存一份
cf-cache-status: HITCloudflare 快取狀態判斷有沒有命中

用 curl 檢查回應 Header

# 檢查某個資源的快取狀態
curl -I https://yoursite.com/style.css

# 重點看這幾行
# cf-cache-status: HIT    ← 有快取
# cache-control: public, max-age=31536000    ← 快取策略
# age: 7200    ← 這份快取已經存在 2 小時
# cf-ray: xxxx-TPE    ← TPE 表示從台北的節點回應

實際排查案例:為什麼改了檔案卻沒更新?

這是最常見的問題。你改了 CSS 或圖片,但訪客看到的還是舊版。排查流程:

Step 1:確認原站有更新

先繞過 CDN,直接存取原站確認檔案是否已經更新:

# 如果你知道原站 IP,可以直接存取
curl -H "Host: yoursite.com" http://原站IP/style.css | head

Step 2:檢查 CDN 快取狀態

curl -I https://yoursite.com/style.css
# 看 cf-cache-status 和 age

如果 cf-cache-status: HIT 而且 age 很大,表示 CDN 還在提供舊的快取。

Step 3:清除快取

到 Cloudflare Dashboard → Caching → Configuration → Purge Cache。

你可以選擇:

  • Purge Everything:清除所有快取。簡單但粗暴,會導致短暫的全站回源。
  • Custom Purge:只清特定 URL。精確但要手動輸入。
  • Purge by Tag/Host:Enterprise 方案才有。

Step 4:如果清了快取還是舊的

那問題不在 CDN,而在瀏覽器快取。叫訪客按 Ctrl+Shift+R(強制重新整理),或者用無痕模式開。

長期解法:用版本化的檔名(style.a1b2c3.css),這樣內容一改,URL 就不同,瀏覽器不可能拿到舊的。

快取命中率的優化策略

快取命中率是衡量 CDN 效能的關鍵指標。Cloudflare 後台可以看到你的 Cache Hit Rate。

理想的快取命中率

  • 靜態網站(部落格、公司官網):90% 以上
  • 混合型網站(電商、有會員系統):60-80%
  • 高度動態網站(社群平台、即時資料):30-50%

提升命中率的方法

  1. 統一 URL:不要用 ?v=1?v=2 來做版本控制,改用檔名 hash。每個不同的 URL 在 CDN 看來就是不同的資源。

  2. 設定合理的 TTL:靜態資源至少 1 天,有 hash 的資源可以 1 年。

  3. 注意 Query String 排序?a=1&b=2?b=2&a=1 對某些 CDN 來說是不同的 URL。Cloudflare 有 Query String Sort 功能可以解決。

  4. 善用 Page Rules(或 Cache Rules)

    • /wp-admin/* → Bypass Cache
    • /wp-content/uploads/* → Cache Everything, Edge TTL 30 days
    • /*.css → Cache Everything, Edge TTL 1 year
  5. 減少 Vary Header 的變化Vary: Accept-Encoding 是正常的,但如果你的原站回傳 Vary: * 或太多 Vary 值,CDN 可能完全不快取。

CDN 與 SSL/TLS 的關係

CDN 和 SSL 的關係經常讓人搞混。當你啟用 CDN Proxy(Cloudflare 的橘色雲朵),SSL 的運作變成兩段:

  1. 訪客 ↔ CDN 邊緣節點:用 Cloudflare 提供的 SSL 憑證
  2. CDN 邊緣節點 ↔ 你的原站:看你的 SSL 模式設定

這就是為什麼 Cloudflare 的 SSL 模式選擇很重要。詳細的 SSL 模式說明,請看 Cloudflare 設定教學 裡的 SSL 段落。

如果你的原站需要 SSL 憑證,可以參考 SSL 憑證設定教學

做完後怎麼確認自己真的有設對

  • curl -I 檢查關鍵頁面的 cf-cache-statuscache-controlage Header。
  • 在 Cloudflare Dashboard 的 Analytics 裡看 Cache Hit Rate,確認命中率符合預期。
  • 至少從不同網路或無痕模式測一次,確認快取與代理後的實際結果。
  • 從使用者視角再跑一次實際流程,不要只看後台畫面。
  • 如果你有改 DNS、Proxy、背景服務或權限,請逐層確認,不要一次判斷全部成功。
  • 測試「更新內容 → 清快取 → 確認更新」的完整流程,確保你的部署流程跟快取策略是配合的。

這一題最常踩的坑

  • 只知道「有經過 CDN」,卻不知道到底是命中還是回源。用 curl -I 看 Header 就能判斷。
  • 資源已更新卻忘了快取層還沒刷新。養成習慣:部署後清快取。
  • 快取規則與部署流程沒有一起設計,導致每次更新都很混亂。
  • Vary Header 設太多,導致同一個資源存了好幾份,命中率暴跌。
  • 忘了 CDN 的快取是「每個邊緣節點獨立的」。你清了台北節點的快取,東京節點可能還有舊的。Purge Everything 會清所有節點。
  • 原站回傳 Cache-Control: privateno-store,CDN 根本不會快取,但你不知道為什麼命中率一直是 0。
  • 忽略 cf-ray Header 裡的機場代碼。cf-ray: xxx-TPE 表示台北,cf-ray: xxx-NRT 表示東京。這能幫你確認請求是從哪個節點回應的。

Troubleshooting:更多常見問題

Q:CDN 會造成資料同步問題嗎? 有可能。如果你更新了圖片但檔名沒變,CDN 可能還在提供舊的圖。這時你需要執行 Purge Cache 操作。詳細設定可參考 Cloudflare 設定教學

Q:小網站也需要 CDN 嗎? 建議開。即使流量不大,CDN 提供的免費 SSL、DDoS 防護與基礎加速,都能讓你的網站更安全、更快。Cloudflare 免費方案零成本,沒有理由不用。

Q:為什麼 cf-cache-status 顯示 DYNAMIC? Cloudflare 預設只快取特定副檔名(.js、.css、.jpg 等)。HTML 頁面預設不快取(顯示 DYNAMIC)。如果你要讓 HTML 也被快取,需要設定 Page Rule 或 Cache Rule,加上 Cache Everything。

Q:多個子網域(subdomain)的快取是獨立的嗎? 是的。www.example.comblog.example.com 的快取完全獨立。每個子網域在每個邊緣節點都有自己的快取空間。

如果你要往下一步走

如果你要真的動手導入,下一篇就看 Cloudflare 免費帳號註冊與 DNS 設定教學。如果你想回頭複習基本概念,看 CDN 基礎教學。DNS 相關問題可以看 DNS 問題排除教學DNS 基礎教學。如果你要讓網站直接套用這些做法,可以搭配侃瑞的 主機方案

需要主機來實作?

侃瑞科技提供 cPanel 虛擬主機與 VPS,教學裡的操作開箱即用。

查看方案 →
LINE 諮詢