一個請求在 Cloudflare 上的完整生命週期
這就是把整個平台串起來的心智模型——只要你畫得出這張圖,其他產品就全部說得通了。
我們要追蹤的是哪一段旅程?
每次你打開一個網頁,瀏覽器都會送出一個 HTTP 請求,這個請求要經過一連串的站點,答案才會回來。在 Cloudflare 上這條路徑是:DNS(網域名稱系統)先找到位址,Anycast 把你導向最近的邊緣資料中心,WAF(網站應用防火牆)檢查請求是否安全,快取(cache)試著立刻回答,只有在需要時,Worker 才會執行你的後端程式並讀取儲存。接著回應會沿著原路一路回家。
下面這張圖把整條路徑畫在一起。由左讀到右:瀏覽器開啟旅程,邊緣 PoP(接入點)負責主要工作(先 WAF、再快取、再 Worker),儲存在最末端,回應再流回來。
把它想成一趟包裹配送
DNS 是在查地址。Anycast 是宅配選了離你最近的轉運站。WAF 是門口的保全。快取是一整排「現貨、可立即出貨」的包裹。Worker 是那位幫你客製組裝訂單的員工,儲存則是後方的大倉庫。大多數時候你根本走不到倉庫——貨架上早就有你的包裹了。
逐站拆解:每一個站點在做什麼
整趟旅程由六個站點組成。每個站點只負責一件事,而且每一站都可能讓旅程「提前結束」——例如快取可以在請求碰到你的程式碼之前就先回答。
1. DNS(網域名稱系統)
把像 shop.com 這樣的名字換成一個 IP 位址。在 Cloudflare 上,這個 IP 是所有邊緣資料中心共用的 Anycast 位址。
2. 邊緣 PoP(接入點)
離你最近的 Cloudflare 資料中心(Point of Presence,接入點)。Anycast 把請求導向這裡,讓來回距離保持最短。
3. WAF(網站應用防火牆)
最先檢查請求。惡意流量(SQL 注入、機器人、濫用)會在碰到後面任何東西之前先被封鎖或要求驗證。
4. 快取(Cache)
如果這個 PoP 已經存有一份還新鮮的回應複本,就立刻送回去——這就是快取命中(HIT)。不需要動用 Worker,也不必回源。
5. Worker(後端)
快取未命中(MISS)時,你的無伺服器程式碼就在這個邊緣節點執行。它決定接下來要做什麼:讀資料、呼叫 API、產生 HTML。
6. 儲存(Storage)
Worker 在這裡讀寫資料:D1(SQL 資料庫)、KV(鍵值儲存)或 R2(檔案儲存)。這是答案掉頭回家之前、旅程的最遠端。
一步一步走,含快取 HIT 與 MISS 分支
現在把同一趟旅程畫成依時間排序的流程。注意那個分支:快取命中(HIT)只要一個短短的往返就能回答;而快取未命中(MISS)必須叫醒 Worker、走到儲存才能回應——而且回應後會把結果存起來,讓下一位訪客拿到 HIT。
怎麼分辨 HIT 還是 MISS
Cloudflare 會用 cf-cache-status 這個回應標頭告訴你結果。第一次請求某個頁面常常是 MISS;再載入一次,通常就會拿到直接從邊緣送出的 HIT。
邊緣節點當下做的那些決定
在那一個邊緣 PoP 裡,幾個是/否的問題就決定了這個請求接下來的命運:它是惡意的嗎?它已經被快取了嗎?有沒有路由把它送去某個 Worker?順著箭頭走,就能看到請求所有可能走的路。
越早結束、越省
請求越早離開這張圖,就越快也越省。一次快取命中會完全跳過 Worker、來源伺服器與儲存——這就是為什麼「快取」是你手上最有力的效能槓桿。
Worker 在這條路徑上的位置
Worker 其實就是一個 fetch 處理函式,由 Cloudflare 在邊緣 PoP 執行——在 WAF 之後、而且只有在快取無法回答時才會跑。下面這段範例剛好對應上面的圖:先試快取,MISS 時才執行後端邏輯並讀取儲存,最後把回應存起來給下次用。
這段程式碼跑在「第 5 站」
env.DB 是 D1(SQL)的 binding(繫結),env.ASSETS 是 KV 的 binding,兩者都是圖中「儲存」這一站。caches.default 就是圖裡的邊緣快取。ctx.waitUntil 讓回應先送出,快取寫入則在背景慢慢完成。
export default {
// Cloudflare runs this at the edge PoP, AFTER the WAF and a cache MISS
async fetch(request, env, ctx) {
const url = new URL(request.url);
// 1) Try the edge cache first
const cache = caches.default;
let response = await cache.match(request);
if (response) {
return response; // cache HIT - the fastest path home
}
// 2) Cache MISS - run back-end logic and read storage
if (url.pathname === "/api/profile") {
const user = await env.DB.prepare(
"SELECT name FROM users WHERE id = ?"
).bind(url.searchParams.get("id")).first();
response = Response.json(user);
} else {
const html = await env.ASSETS.get("index.html");
response = new Response(html, {
headers: { "content-type": "text/html" },
});
}
// 3) Save to the edge cache for the next visitor, then return
response.headers.append("Cache-Control", "max-age=60");
ctx.waitUntil(cache.put(request, response.clone()));
return response;
},
};看看你打到了哪個 PoP
cf-ray 標頭結尾有一組 3 個字母的機場代碼——那就是替你服務的邊緣資料中心。
curl -sI https://example.com | grep -i cf-ray # cf-ray: 8a1f...-LHR (LHR = London)觀察快取 HIT 與 MISS
連跑兩次。第一次常常是 MISS;第二次通常是 HIT,直接從邊緣送出。
curl -sI https://example.com/logo.png | grep -i cf-cache-status # cf-cache-status: HIT確認 Worker 有跑到
在 Worker 裡加一個自訂標頭(例如 response.headers.set('x-served-by', 'worker')),再去回應裡找它,就能證明是你的程式碼回答的。
關鍵名詞,一次說清楚
DNS(網域名稱系統)
網際網路的電話簿。它把人看得懂的名字(shop.com)翻譯成電腦真正能連線的數字 IP 位址。
Anycast(任播)
同一個 IP 位址,同時從上百個據點對外宣告。網路會自動把每個請求送到最近的那個,所以使用者永遠打到附近的邊緣節點。
邊緣 / PoP(接入點)
「邊緣(edge)」指的是靠近使用者的伺服器,而不是一座遙遠的資料中心。PoP(Point of Presence,接入點)就是其中一個據點——Cloudflare 在全球 330 多個城市都有。
WAF(網站應用防火牆)
Web Application Firewall(網站應用防火牆)。它在邊緣檢查每個請求,在常見攻擊(SQL 注入、XSS 跨站腳本)和惡意機器人碰到你的應用之前就先擋下來。
快取 HIT/MISS(命中/未命中)
HIT(命中)表示邊緣手上已有新鮮複本,立刻回答。MISS(未命中)表示它得去抓一份新的(向 Worker 或你的來源伺服器),再存起來。
Origin(來源伺服器)
你自己那台存放原始內容的伺服器或服務。只有當邊緣無法用快取或 Worker 回答時,Cloudflare 才會回到來源伺服器——這趟來回就叫「回源」。
小提示與常見陷阱
千萬別快取每位使用者專屬的頁面
如果把已登入的儀表板快取在邊緣,某位使用者可能會看到別人的頁面。請替私人回應加上 Cache-Control: private, no-store,讓它們一定走 Worker。
- 整條鏈(DNS、邊緣、WAF、快取)只有在你的 DNS 紀錄「經過代理」時才會啟動——也就是儀表板上的橘色雲朵。
- 靜態檔案(圖片、CSS、JS)非常適合快取;動態、個人化的回應通常不該快取。
- 快取命中(HIT)完全不會執行你的 Worker,所以不計 Worker 請求、也不增加延遲。
- cf-ray 能標示是哪個 PoP、哪一個請求;回報問題給客服時請保留它。
- 接下來去讀 DNS、CDN、WAF 和 Workers 的章節——每一章都正好是這張圖裡的一個站點。