Bỏ qua đến nội dung chính
CDNCloudflareperformanceHTTP cacheweb infrastructure

CDN Là Gì? Origin, Edge, Cache Header Cho Dev

CDN là gì giải thích từ 0: origin server, edge POP, cache header, TTL, purge. Cách config CDN đúng cho web hiện đại — không sai 1 chi tiết.

Xuất bản 7 phút đọc

CDN là gì? Câu trả lời ngắn: mạng máy chủ phân bố toàn cầu cache nội dung gần user. Bài này đi qua nguyên lý + cách config Cache-Control đúng để CDN làm việc thay anh.

Định nghĩa và lợi ích

CDN (Content Delivery Network) = origin server + nhiều edge POP (Point of Presence) trên thế giới. User Hà Nội request → router gần nhất serve từ Hong Kong/Singapore POP thay vì origin US. Latency giảm 5-10x cho asset cache hit.

Lợi ích chính:

  • Tốc độ — TTFB < 50ms cho cache hit từ edge gần
  • Giảm tải origin — 90% request không tới server gốc
  • DDoS protection — hấp thụ flood ở edge
  • HTTPS termination, HTTP/3, Brotli compression auto
  • Geo routing, A/B testing ở edge

Luồng request qua CDN

User → DNS → CDN edge nearest → có cache?
                                    ├─ Yes → trả response ngay
                                    └─ No  → fetch origin → cache → trả user

Request thứ 2 từ user khác cùng region thường hit cache → nhanh hơn nhiều.

Cache-Control — header quan trọng nhất

Cache-Control: public, max-age=31536000, immutable
Cache-Control: public, max-age=60, stale-while-revalidate=86400
Cache-Control: private, no-cache
Cache-Control: no-store
DirectiveNghĩa
publicCDN + browser cache
privateChỉ browser, CDN không cache
max-age=NCache fresh trong N giây
immutableAsset không bao giờ đổi (file versioned)
stale-while-revalidate=NSau hết hạn vẫn serve cache cũ + revalidate ngầm trong N giây
no-cachePhải revalidate origin trước khi serve (vẫn cache)
no-storeKhông cache đâu cả — dùng cho payment, secret

Strategy theo loại asset

LoạiCache-ControlLý do
JS/CSS versioned (app.abc.js)public, max-age=31536000, immutableURL khác mỗi deploy → cache 1 năm
Image staticpublic, max-age=259200030 ngày, có thể purge khi cần
HTMLpublic, max-age=0, s-maxage=60, swr=86400Browser luôn check, CDN cache 60s + swr
API GET (data ít đổi)public, max-age=300, swr=605 phút fresh, swr 1 phút
API GET (per-user)private, max-age=60Browser cache, CDN không
API mutation (POST)no-storeKhông cache POST
/me, /adminprivate, no-cacheCá nhân, revalidate mỗi lần

stale-while-revalidate — bí mật của UX nhanh

swr cho phép serve cache cũ trong khi fetch mới ngầm. User không bao giờ chờ:

Cache-Control: max-age=60, stale-while-revalidate=86400

t=0:    request 1 → fetch origin, cache 60s
t=30:   request 2 → cache fresh, serve ngay
t=90:   request 3 → cache stale (>60s), serve cũ + fetch ngầm + cache mới
t=91:   request 4 → cache fresh (vừa update), serve ngay

User vẫn nhận response trong <50ms. Origin được hit nhẹ nhàng. Đây là pattern mạnh nhất cho HTML/API public.

Versioned filename + immutable

Webpack/Vite/Next.js auto bundle với hash: app.a3f8c2.js. Khi code đổi, hash đổi, URL đổi:

Build 1: /app.a3f8c2.js → cache 1 năm
Build 2: /app.b9e1d4.js → URL mới, cache 1 năm

HTML reference URL mới (không cache HTML lâu)

immutable directive bảo browser KHÔNG cần revalidate dù user nhấn F5. Tiết kiệm 1 round trip.

Purge cache

Versioned asset: không cần purge. HTML: cần purge khi deploy:

# Cloudflare API — purge URL cụ thể
curl -X POST \
  "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"files":["https://alodev.vn/", "https://alodev.vn/blog"]}'

# Purge by tag (cần Enterprise hoặc Cloudflare Pro với cache tag)
--data '{"tags":["blog-list"]}'

# Purge everything (cẩn thận — origin bị spike)
--data '{"purge_everything":true}'

CI/CD chạy purge sau khi deploy. Đừng purge_everything trừ trường hợp bất khả kháng — origin bị flood request.

Vary header — pitfall thường gặp

Vary báo CDN cache riêng cho mỗi giá trị header:

Vary: Accept-Encoding   ✓ Cache riêng gzip/br/identity
Vary: Accept-Language   ✓ Cache riêng vi/en
Vary: User-Agent        ⚠ Hàng nghìn user-agent → cache thracking
Vary: Authorization     ✗ Mỗi user 1 cache → gần như tắt cache

Quy tắc: chỉ Vary những header có ít giá trị khác nhau.

Metric monitor

  • Cache hit ratio — mục tiêu > 90% cho asset, > 70% cho HTML
  • TTFB phân biệt edge vs origin — < 50ms edge, < 200ms origin
  • Origin request rate — đột biến = cache invalidation accident

Kết luận

CDN là gì? Đó là một trong những đầu tư hạ tầng có ROI cao nhất. Setup đúng Cache-Control + versioned asset + swr, anh sẽ thấy TTFB từ vài trăm ms xuống vài chục ms — Web Vitals cải thiện rõ rệt. Tham khảo Web Vitals để đo impact thực tế lên SEO.

Zalo