Tuần 03: Networking Fundamentals — DNS, CDN, TCP/UDP, TLS
“Mỗi request từ browser đến server là một cuộc hành trình qua hàng chục node, hàng nghìn km cáp quang. Hiểu từng bước trong hành trình đó — đó là điều biến một Backend Dev thành System Architect.”
Tags: system-design networking dns cdn tls alex-xu Prerequisite: Tuan-02-Back-of-the-envelope Liên quan: Tuan-05-Load-Balancer · Tuan-06-Cache-Strategy · Tuan-09-Rate-Limiter · Tuan-12-API-Design · Tuan-13-Monitoring-Observability
1. Context & Why
Analogy đời thường
Hieu, tưởng tượng em muốn gửi một bưu kiện cho bạn ở Đà Nẵng.
Gửi thư qua bưu điện (TCP):
- Em viết địa chỉ người nhận lên bưu kiện → DNS resolution (tìm địa chỉ IP từ tên miền)
- Bưu điện quận em nhận bưu kiện → Local DNS resolver
- Bưu kiện đi qua nhiều trạm trung chuyển (HCM → Bình Định → Đà Nẵng) → Network hops (routing)
- Mỗi trạm kiểm tra bưu kiện có hợp lệ không → TCP checksum, packet validation
- Người nhận ký xác nhận đã nhận → TCP ACK (acknowledgement)
- Nếu bưu kiện bị mất, bưu điện gửi lại → TCP retransmission
Gọi điện thoại (UDP):
- Kết nối trực tiếp, nói là nghe liền → Không cần 3-way handshake
- Nếu mất tín hiệu vài giây, không ai lặp lại câu vừa nói → Không retransmit
- Tốc độ là ưu tiên, chấp nhận mất mát nhỏ → Real-time: video call, game, DNS query
CDN — Kho hàng trung chuyển:
- Thay vì gửi mỗi bưu kiện từ HCM → Đà Nẵng, em đặt sẵn hàng tồn kho ở Đà Nẵng → CDN edge server
- Khách Đà Nẵng mua hàng → lấy từ kho Đà Nẵng, không cần chờ ship từ HCM → Cache hit
- Kho Đà Nẵng hết hàng → liên hệ HCM lấy thêm → Cache miss → Origin fetch
TLS — Niêm phong bưu kiện:
- Em dán seal chống mở lén → Encryption
- Bưu điện kiểm tra seal có hợp lệ → Certificate verification
- Chỉ người nhận có chìa khoá mở → Asymmetric + symmetric encryption
Tại sao Networking đặt ở Tuần 3?
Sau khi đã biết scale (Tuần 1) và estimate (Tuần 2), giờ em cần hiểu con đường mà mỗi request đi qua. Mọi quyết định kiến trúc — load balancing, caching, database replication — đều dựa trên hiểu biết về networking:
- DNS quyết định request đến server nào
- CDN quyết định content được serve từ đâu
- TCP/UDP quyết định data được truyền như thế nào
- TLS quyết định data có bị đọc trộm không
- HTTP/2, HTTP/3 quyết định performance của application layer
Trong interview, khi nói “user gõ URL và nhấn Enter”, interviewer muốn em kể được toàn bộ hành trình — không chỉ “gửi request đến server”.
2. Deep Dive — Các khái niệm cốt lõi
2.1 OSI Model — Chỉ cần nhớ 3 layers cho System Design
OSI có 7 layers, nhưng trong System Design Interview, em chỉ cần master 3 layers:
| Layer | Tên | Protocol | Vai trò trong System Design |
|---|---|---|---|
| L3 — Network | Internet Protocol (IP) | IPv4, IPv6, ICMP | Routing, IP addressing, subnet design |
| L4 — Transport | TCP, UDP | TCP, UDP, QUIC | Connection management, load balancing (L4 LB) |
| L7 — Application | HTTP, DNS, gRPC | HTTP/1.1, HTTP/2, HTTP/3, DNS, WebSocket | API design, reverse proxy, CDN, WAF |
Tại sao chỉ 3 layers?
- L3: Khi nói về VPC, subnet, security group, IP whitelisting → L3
- L4: Khi nói về TCP connection pooling, UDP cho real-time, L4 load balancer (NLB) → L4
- L7: Khi nói về HTTP routing, CDN caching, API gateway, WAF → L7
Aha Moment: L4 Load Balancer (AWS NLB) nhanh hơn L7 Load Balancer (AWS ALB) vì nó chỉ nhìn IP + port, không cần parse HTTP headers. Nhưng L7 LB mới có thể route dựa trên URL path, cookies, headers → Tuan-05-Load-Balancer.
2.2 DNS — Domain Name System
DNS là gì?
DNS là phonebook của Internet. Khi em gõ google.com, browser không biết gửi request đi đâu — nó cần DNS để translate google.com → 142.250.80.46.
DNS Resolution: Recursive vs Iterative
Recursive Resolution (cách browser thường dùng):
- Browser hỏi Recursive Resolver (ISP hoặc 8.8.8.8): “IP của
api.example.comlà gì?” - Resolver chưa biết → hỏi Root Name Server (
.) - Root trả lời: “Tao không biết, nhưng
.comnằm ở TLD server này” - Resolver hỏi TLD Name Server (
.com) - TLD trả lời: “
example.comnằm ở Authoritative NS này” - Resolver hỏi Authoritative Name Server (
ns1.example.com) - Authoritative NS trả lời: “
api.example.com=93.184.216.34” - Resolver cache kết quả và trả cho browser
Iterative Resolution (giữa các DNS servers):
Ở mỗi bước trên, DNS server trả về referral (gợi ý hỏi server tiếp theo), thay vì tự đi hỏi hộ. Recursive resolver là nơi duy nhất thực hiện toàn bộ chuỗi query.
Key insight: DNS resolution trung bình mất 20–120ms cho lần đầu tiên (uncached). Sau đó, kết quả được cache tại nhiều tầng (browser cache → OS cache → Resolver cache) theo TTL.
DNS Record Types — Bảng tra cứu
| Record Type | Mục đích | Ví dụ | Use case |
|---|---|---|---|
| A | Map domain → IPv4 | example.com → 93.184.216.34 | Record cơ bản nhất |
| AAAA | Map domain → IPv6 | example.com → 2606:2800:220:1:... | IPv6 support |
| CNAME | Alias domain → domain khác | www.example.com → example.com | Subdomain aliasing, CDN integration |
| MX | Mail server | example.com → mail.example.com (priority 10) | Email routing |
| TXT | Text record | example.com → "v=spf1 include:_spf.google.com" | SPF, DKIM, domain verification |
| NS | Nameserver delegation | example.com → ns1.example.com | DNS delegation |
| SRV | Service discovery | _http._tcp.example.com → 0 5 80 server.example.com | Service location (Kubernetes, SIP) |
| CAA | Certificate Authority Authorization | example.com → 0 issue "letsencrypt.org" | Chỉ cho phép CA nào cấp cert |
Lưu ý: CNAME không thể đặt ở root domain (apex domain).
example.comkhông thể có CNAME, chỉwww.example.commới được. Nhiều DNS provider cung cấp ALIAS/ANAME record để workaround → quan trọng khi setup CDN.
TTL (Time To Live)
TTL quyết định DNS record được cache bao lâu:
| TTL | Thời gian | Use case |
|---|---|---|
| 60s | 1 phút | Migration/failover — cần chuyển traffic nhanh |
| 300s | 5 phút | Default tốt — cân bằng giữa performance và flexibility |
| 3600s | 1 giờ | Ổn định — domain ít thay đổi IP |
| 86400s | 1 ngày | Static — domain cực kỳ ổn định |
Pitfall: Trước khi migration, hạ TTL xuống 60s ít nhất 48 giờ trước để đảm bảo tất cả resolver đã expire cache cũ. Nhiều người quên bước này → migration bị dính cache cũ hàng giờ.
DNS-based Load Balancing
Round Robin DNS: Trả về nhiều IP cho cùng một domain, client chọn ngẫu nhiên.
example.com. 300 IN A 10.0.1.1
example.com. 300 IN A 10.0.1.2
example.com. 300 IN A 10.0.1.3
Weighted DNS: Trả về IP với tỉ lệ khác nhau (ví dụ: 70% traffic đến server mới, 30% server cũ) → dùng cho canary deployment.
GeoDNS: Trả về IP gần nhất với user:
- User ở VN → IP của server Singapore
- User ở Mỹ → IP của server US-East
Hạn chế của DNS load balancing: Không health-check real-time. Nếu server A chết, DNS vẫn trả về IP của A cho đến khi TTL expire. Đó là lý do cần DNS failover kết hợp health check.
DNS Failover
DNS Failover = DNS + Health Check:
- Health checker liên tục ping các server (TCP check hoặc HTTP check)
- Nếu server A không response → DNS tự động loại IP của A khỏi response
- Thời gian failover = Health check interval + DNS TTL propagation
Ví dụ với TTL=60s và health check interval=30s:
Đây là lý do AWS Route 53 khuyến khích TTL thấp (60s) kết hợp health check cho mission-critical services.
2.3 CDN — Content Delivery Network
CDN là gì?
CDN là mạng lưới edge servers phân tán toàn cầu, đặt gần user nhất có thể. Mục đích: giảm latency bằng cách serve content từ server gần thay vì origin server xa.
Không có CDN:
User (VN) → Origin Server (US-East): ~250ms RTT
Có CDN:
User (VN) → CDN Edge (Singapore): ~30ms RTT
Giảm ~220ms cho mỗi request static content. Với trang web có 50 static resources → tiết kiệm 11 giây thời gian load.
Push CDN vs Pull CDN
| Đặc điểm | Push CDN | Pull CDN |
|---|---|---|
| Cơ chế | Origin chủ động push content lên CDN | CDN tự pull từ origin khi có request đầu tiên |
| Cache invalidation | Chủ động: push version mới | Dựa trên TTL hoặc purge API |
| Traffic đến origin | Thấp — chỉ khi push | Có spike khi cache miss đồng loạt |
| Phù hợp | Content ít thay đổi, biết trước (video, firmware) | Content thay đổi thường xuyên (website, API response) |
| Ví dụ | Netflix pre-push movie files đến edge | Cloudflare pull HTML/CSS/JS khi user request |
| Storage cost | Cao — replicate ở mọi edge | Thấp — chỉ cache ở edge có demand |
Thực tế: Hầu hết web app dùng Pull CDN. Push CDN chủ yếu cho video streaming (Netflix Open Connect) và software distribution.
CDN Cache Invalidation
Đây là một trong những hard problems trong computer science:
1. TTL-based expiry:
Cache-Control: public, max-age=31536000
- Content được cache 1 năm
- Kết hợp cache busting bằng filename hash:
app.a1b2c3.js - Khi deploy mới → filename mới → CDN fetch file mới
2. Purge API:
# Cloudflare purge specific URL
curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
-H "Authorization: Bearer {token}" \
-d '{"files":["https://example.com/styles.css"]}'3. Versioned URLs:
https://cdn.example.com/v2/api/config.json
https://cdn.example.com/assets/logo.png?v=20260318
4. Stale-while-revalidate:
Cache-Control: public, max-age=600, stale-while-revalidate=30
- Serve stale content trong 30s trong khi background revalidate → user không bao giờ thấy cache miss delay.
CDN Edge Locations & Origin Shield
Edge Location: Server CDN gần user. Cloudflare có ~300 edge locations, CloudFront ~450+.
Origin Shield: Một layer cache trung gian giữa edge và origin.
User → Edge (SGP) ─┐
User → Edge (HK) ─┤→ Origin Shield (Tokyo) → Origin Server (US)
User → Edge (TW) ─┘
Tại sao cần Origin Shield?
Không có Origin Shield:
- 100 edge servers đồng loạt cache miss → 100 requests đến origin → thundering herd / cache stampede
Có Origin Shield:
- 100 edge servers miss → tất cả hỏi Origin Shield → Origin Shield chỉ gửi 1 request đến origin → request collapsing
Ví dụ: 200 edge locations, mỗi edge 100 req/s, miss rate 5%. Không có shield: req/s đến origin. Có shield (collapse ratio 95%): req/s. Giảm 20 lần load lên origin.
2.4 TCP vs UDP
TCP — Transmission Control Protocol
3-Way Handshake:
| Bước | Client → Server | Mục đích |
|---|---|---|
| 1. SYN | Client gửi SYN (seq=x) | “Tao muốn kết nối” |
| 2. SYN-ACK | Server trả SYN-ACK (seq=y, ack=x+1) | “OK, tao sẵn sàng” |
| 3. ACK | Client gửi ACK (ack=y+1) | “Nhận rồi, bắt đầu gửi data” |
Overhead: 1 RTT (round trip time) chỉ để establish connection, trước khi gửi bất kỳ data nào.
Với cross-region RTT = 150ms:
Connection Pooling
Thay vì tạo TCP connection mới cho mỗi request, tái sử dụng connections:
Không có pooling:
Request 1: [handshake 150ms] + [data 50ms] = 200ms
Request 2: [handshake 150ms] + [data 50ms] = 200ms
Request 3: [handshake 150ms] + [data 50ms] = 200ms
Total: 600ms
Có pooling:
Request 1: [handshake 150ms] + [data 50ms] = 200ms (tạo connection)
Request 2: [data 50ms] = 50ms (reuse connection)
Request 3: [data 50ms] = 50ms (reuse connection)
Total: 300ms → tiết kiệm 50%
Production tip: Luôn dùng connection pooling cho database connections (PgBouncer cho PostgreSQL, ProxySQL cho MySQL) và HTTP connections (keep-alive).
Keep-Alive
HTTP Keep-Alive giữ TCP connection mở sau khi response xong:
Connection: keep-alive
Keep-Alive: timeout=5, max=100
timeout=5: Đợi 5 giây trước khi đóng idle connectionmax=100: Tối đa 100 requests trên connection này
HTTP/1.1 mặc định bật keep-alive. HTTP/2 bỏ khái niệm keep-alive vì dùng multiplexing — một connection handle tất cả requests.
UDP — User Datagram Protocol
UDP không có: handshake, acknowledgement, retransmission, ordering guarantee.
Khi nào dùng UDP?
| Use case | Lý do dùng UDP |
|---|---|
| DNS queries | Payload nhỏ (< 512 bytes), cần nhanh, retry ở application layer |
| Video/Audio streaming | Mất vài frame không sao, delay mới là kẻ thù |
| Online gaming | Player position cập nhật liên tục, data cũ vô nghĩa |
| IoT sensor data | Gửi liên tục, mất 1 reading không ảnh hưởng |
| QUIC (HTTP/3) | Build reliability lên trên UDP, bypass TCP limitations |
Aha Moment: DNS dùng UDP cho queries nhỏ (< 512 bytes) nhưng chuyển sang TCP cho responses lớn (zone transfer, DNSSEC responses > 512 bytes). Đây là lý do DNS server phải listen cả port 53/UDP và 53/TCP.
2.5 TLS/HTTPS — Transport Layer Security
TLS 1.3 Handshake
TLS 1.3 (2018) cải thiện đáng kể so với TLS 1.2:
| Metric | TLS 1.2 | TLS 1.3 |
|---|---|---|
| Handshake RTTs | 2 RTT | 1 RTT |
| 0-RTT resumption | Không | Có |
| Cipher suites | 37+ (nhiều insecure) | 5 (chỉ strong ciphers) |
| Forward secrecy | Tuỳ chọn | Bắt buộc |
TLS 1.3 Handshake (1-RTT):
| Bước | Nội dung | Hướng |
|---|---|---|
| 1 | Client Hello + Key Share + Supported Ciphers | Client → Server |
| 2 | Server Hello + Key Share + Certificate + Finished | Server → Client |
| 3 | Client Finished + Application Data | Client → Server |
0-RTT Resumption (TLS 1.3):
- Nếu client đã kết nối server trước đó → gửi encrypted data ngay trong Client Hello
- Tiết kiệm 1 RTT → latency = 0 RTT cho resumption
Cảnh báo bảo mật: 0-RTT data có thể bị replay attack. Chỉ dùng cho idempotent requests (GET), KHÔNG BAO GIỜ cho POST/PUT/DELETE.
Với RTT = 150ms:
Với TLS 1.3 + 0-RTT resumption:
Certificate Chain
Root CA (DigiCert, Let's Encrypt ISRG Root)
└── Intermediate CA (Let's Encrypt R3)
└── Leaf Certificate (example.com)
- Root CA: Được cài sẵn trong OS/browser. Tự ký (self-signed).
- Intermediate CA: Ký bởi Root CA. Dùng để ký leaf cert → nếu intermediate bị compromise, chỉ revoke intermediate, không ảnh hưởng root.
- Leaf Certificate: Cert của website, chứa domain name + public key.
Production tip: Server phải gửi cả leaf cert + intermediate cert (certificate chain). Nếu chỉ gửi leaf → client không verify được → SSL error trên một số browser/device.
mTLS (Mutual TLS)
TLS thông thường: chỉ server chứng minh danh tính (server cert). mTLS: cả client và server đều phải chứng minh danh tính.
Use cases:
- Service-to-service communication trong microservices (Istio, Linkerd)
- API authentication cho partners (thay thế API key)
- Zero Trust Architecture — không tin bất kỳ ai, kể cả trong internal network
Xem chi tiết mTLS trong microservices: Tuan-11-Microservices
Certificate Pinning
Certificate Pinning = Client hard-code hash của certificate (hoặc public key) mà nó tin tưởng.
Vấn đề giải quyết: Ngăn attacker dùng cert hợp lệ nhưng từ CA khác (ví dụ: compromised CA cấp cert cho google.com).
Rủi ro: Nếu cert expire hoặc cần rotate → app bị lock out. Nhiều công ty đã bỏ pinning vì operational overhead quá cao (Google đã deprecate HPKP).
Khuyến nghị hiện đại: Dùng Certificate Transparency logs thay vì pinning. Cho phép giám sát cert bất thường mà không gây lock-out risk.
2.6 HTTP/2 vs HTTP/3 (QUIC)
| Feature | HTTP/1.1 | HTTP/2 | HTTP/3 (QUIC) |
|---|---|---|---|
| Transport | TCP | TCP | UDP |
| Multiplexing | Không (1 req/connection) | Có (nhiều stream/connection) | Có |
| Head-of-line blocking | Cả HTTP & TCP | HTTP: không. TCP: có | Không (cả 2 level) |
| Header compression | Không | HPACK | QPACK |
| Handshake | TCP + TLS = 2–3 RTT | TCP + TLS = 2–3 RTT | 1 RTT (0-RTT resumption) |
| Connection migration | Không | Không | Có (dựa trên Connection ID, không IP) |
Head-of-line blocking problem trong HTTP/2:
HTTP/2 multiplexes nhiều streams trên 1 TCP connection. Nhưng nếu 1 TCP packet bị mất → TCP buộc phải đợi retransmit packet đó → tất cả streams đều bị block (vì TCP đảm bảo ordered delivery).
HTTP/3 (QUIC) giải quyết bằng cách: mỗi stream là independent ở transport layer. Mất packet của stream A không ảnh hưởng stream B.
Connection Migration (HTTP/3):
- User đang dùng WiFi → chuyển sang 4G → IP thay đổi
- HTTP/2 (TCP): Connection bị drop, phải reconnect (handshake lại)
- HTTP/3 (QUIC): Connection vẫn sống vì dùng Connection ID thay vì IP tuple → seamless transition
Aha Moment: HTTP/3 build reliability lên UDP (tương tự TCP nhưng ở user-space). Nó không phải “UDP thô” — nó có congestion control, retransmission, flow control. Nhưng vì nằm ở user-space, nên có thể iterate nhanh hơn TCP (kernel-space).
3. Back-of-the-envelope — Networking Estimation
3.1 DNS Lookup Time Estimation
Cold DNS lookup (uncached):
Warm DNS lookup (cached at resolver):
Browser cached:
Thực tế: Với Chrome, DNS prefetch (
<link rel="dns-prefetch" href="//api.example.com">) giảm perceived DNS latency xuống 0ms cho subsequent navigations.
3.2 CDN Cache Hit Ratio — Impact on Latency
Giả sử:
- Origin latency: 250ms (cross-region)
- CDN edge latency: 30ms (same region)
- Cache hit ratio:
| Cache Hit Ratio () | Avg Latency | So với không CDN |
|---|---|---|
| 0% (no CDN) | baseline | |
| 50% | giảm 44% | |
| 80% | giảm 70% | |
| 90% | giảm 79% | |
| 95% | giảm 84% | |
| 99% | giảm 87% |
Target: Production CDN nên đạt cache hit ratio >= 90% cho static assets. API responses thường thấp hơn (~60–80%).
3.3 Bandwidth Savings with CDN
Giả sử hệ thống serve 10M pageviews/day, avg page size = 2MB (including images, JS, CSS):
Tiết kiệm: 18 TB/day bandwidth từ origin.
Chi phí tiết kiệm (giả sử AWS bandwidth = $0.09/GB):
CDN cost (Cloudflare Pro: $20/month, Enterprise: custom) thường rẻ hơn nhiều so với origin bandwidth cost. Đây là lý do CDN gần như luôn có ROI dương.
3.4 TLS Handshake Overhead
Full HTTPS connection (first request):
| Protocol | RTT = 30ms (CDN) | RTT = 150ms (cross-region) |
|---|---|---|
| HTTP (no TLS) | 60ms | 300ms |
| HTTPS (TLS 1.2) | 120ms | 600ms |
| HTTPS (TLS 1.3) | 90ms | 450ms |
| HTTP/3 (QUIC) | 60ms | 300ms |
| HTTP/3 (0-RTT) | 30ms | 150ms |
Aha Moment: HTTP/3 với 0-RTT resumption có latency tương đương plain HTTP — nhưng vẫn encrypted. Đây là tương lai.
TLS chiếm 33% connection time. Đó là lý do connection reuse (keep-alive, HTTP/2 multiplexing) cực kỳ quan trọng — amortize TLS cost qua nhiều requests.
4. Security First — Networking Threats & Defenses
4.1 DNS Poisoning / DNS Spoofing
Attack vector: Attacker gửi fake DNS response đến resolver trước khi real response đến → resolver cache IP giả → tất cả user bị redirect đến server của attacker.
Hậu quả: Phishing, man-in-the-middle, data theft.
Mitigations:
- DNSSEC (DNS Security Extensions): Ký DNS records bằng cryptographic signature → resolver verify chữ ký trước khi accept response
- DNS over HTTPS (DoH) / DNS over TLS (DoT): Encrypt DNS queries → ngăn eavesdropping và tampering
- Randomize source port + transaction ID: Tăng entropy, khó guess → khó poison
4.2 DNSSEC — How it works
Root Zone (signed by Root KSK)
→ .com TLD (signed, DS record in root zone)
→ example.com (signed, DS record in .com zone)
→ A record: 93.184.216.34 (RRSIG signature attached)
- Mỗi zone có ZSK (Zone Signing Key) ký records và KSK (Key Signing Key) ký ZSK
- Parent zone chứa DS record (hash of child’s KSK) → chain of trust từ root đến leaf
- Resolver validate từng bước → nếu signature sai → SERVFAIL, không trả kết quả
Thực tế: DNSSEC adoption vẫn thấp (~30% domains). Lý do: phức tạp khi operate (key rotation), có thể gây outage nếu misconfigure, và tăng DNS response size (UDP → TCP fallback nhiều hơn).
4.3 DDoS via DNS Amplification
Cơ chế:
- Attacker gửi DNS query nhỏ (~60 bytes) đến open resolver, spoof source IP = victim’s IP
- Resolver trả response lớn (~3000 bytes) cho victim → amplification factor ~50x
- Attacker dùng botnet gửi hàng triệu queries → victim bị flood
Mitigations:
- Rate limiting trên DNS resolver
- BCP38/BCP84: ISP filter spoofed source IPs
- Response Rate Limiting (RRL): DNS server giới hạn identical responses/giây
- Anycast DNS: Phân tán attack traffic qua nhiều PoPs
4.4 CDN as DDoS Shield
CDN (đặc biệt Cloudflare, AWS Shield) là tuyến phòng thủ DDoS đầu tiên:
- Anycast network: Attack traffic bị phân tán qua 300+ edge locations → không node nào bị overwhelm
- Rate limiting at edge: Block suspicious traffic trước khi đến origin
- WAF (Web Application Firewall): Filter L7 attacks (SQL injection, XSS) tại edge
- Always-on DDoS protection: Tự động detect và mitigate attacks
Ví dụ: Cloudflare đã mitigate DDoS attack 71M req/s (2023). Nếu origin trực tiếp chịu → chỉ cần 10K req/s là sập.
4.5 TLS Certificate Management
| Concern | Best Practice |
|---|---|
| Cert expiry | Auto-renew với Let’s Encrypt (cert-manager trên K8s) |
| Private key protection | Lưu trong HSM hoặc KMS, không bao giờ commit vào git |
| Certificate transparency | Monitor CT logs cho domain của mình → phát hiện unauthorized cert |
| Revocation | Dùng OCSP Stapling (server đính kèm OCSP response) thay vì CRL check (chậm) |
| Weak ciphers | Chỉ cho phép TLS 1.2+ và strong cipher suites |
4.6 HSTS — HTTP Strict Transport Security
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
- max-age=63072000: Browser nhớ dùng HTTPS trong 2 năm
- includeSubDomains: Áp dụng cho tất cả subdomain
- preload: Đăng ký vào HSTS preload list → browser luôn dùng HTTPS, kể cả lần đầu tiên
Quan trọng: Nếu bật HSTS mà cert bị lỗi → website hoàn toàn không truy cập được (browser không cho bypass). Đảm bảo cert management ổn định trước khi enable.
5. DevOps/Ops-Light — Hands-on Configuration
5.1 DNS Tools — dig & nslookup
# === dig — DNS lookup chi tiết ===
# Lookup A record
dig example.com A
# Lookup với specific DNS server (Google DNS)
dig @8.8.8.8 example.com A
# Trace full resolution path (recursive → root → TLD → auth)
dig +trace example.com
# Chỉ lấy answer section (clean output)
dig +short example.com
# Kiểm tra TTL còn lại
dig example.com | grep -A1 "ANSWER SECTION"
# ;; ANSWER SECTION:
# example.com. 234 IN A 93.184.216.34
# ^ TTL còn 234 giây
# Lookup MX record (mail server)
dig example.com MX +short
# 10 mail.example.com.
# Lookup CNAME
dig www.example.com CNAME +short
# Check DNSSEC
dig example.com +dnssec +short
# === nslookup — Simple DNS lookup ===
nslookup example.com
nslookup -type=MX example.com
nslookup example.com 8.8.8.8 # dùng Google DNS5.2 Cloudflare DNS + CDN Setup
# 1. Thêm domain vào Cloudflare (sau khi đổi NS records)
# Dashboard: cloudflare.com → Add Site → chọn plan
# 2. Verify DNS propagation
dig NS example.com +short
# Expected: xxx.ns.cloudflare.com, yyy.ns.cloudflare.com
# 3. Kiểm tra CDN hoạt động
curl -sI https://example.com | grep -E "cf-ray|cf-cache-status"
# cf-cache-status: HIT ← CDN đang serve cached content
# cf-ray: 8a1b2c3d4e5f6-SIN ← Served từ Singapore edge
# cf-cache-status values:
# HIT — served from CDN cache
# MISS — fetched from origin, now cached
# BYPASS — CDN not caching (dynamic content)
# EXPIRED — cache expired, revalidating
# DYNAMIC — Cloudflare determined content is dynamic5.3 AWS CloudFront Setup (CLI)
# Tạo CloudFront distribution với S3 origin
aws cloudfront create-distribution \
--origin-domain-name my-bucket.s3.amazonaws.com \
--default-root-object index.html \
--query 'Distribution.DomainName'
# Tạo cache invalidation (purge)
aws cloudfront create-invalidation \
--distribution-id E1234567890 \
--paths "/*"
# Kiểm tra distribution status
aws cloudfront get-distribution --id E1234567890 \
--query 'Distribution.Status'5.4 SSL Certificate với Let’s Encrypt
# === Certbot — Auto SSL certificate ===
# Cài đặt certbot
sudo apt install certbot python3-certbot-nginx # Ubuntu/Debian
# Tạo cert cho domain (tự động configure Nginx)
sudo certbot --nginx -d example.com -d www.example.com
# Tạo cert only (manual configure)
sudo certbot certonly --standalone -d example.com
# Kiểm tra cert
sudo certbot certificates
# Certificate Name: example.com
# Expiry Date: 2026-06-16 (VALID: 89 days)
# Auto-renew (certbot tự thêm cron/systemd timer)
sudo certbot renew --dry-run
# Manual renew
sudo certbot renew
# === Kiểm tra TLS của website ===
# OpenSSL check
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | \
openssl x509 -noout -dates -subject -issuer
# Check TLS version và cipher
openssl s_client -connect example.com:443 -tls1_3 2>/dev/null | \
grep "Protocol\|Cipher"
# Protocol : TLSv1.3
# Cipher : TLS_AES_256_GCM_SHA3845.5 Nginx TLS Configuration (Production-grade)
# /etc/nginx/conf.d/example.com.conf
# Redirect HTTP → HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
# === SSL Certificate ===
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# === TLS Protocol & Ciphers ===
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# === OCSP Stapling ===
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# === SSL Session Cache (connection reuse) ===
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off; # Disable for perfect forward secrecy
# === Security Headers ===
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# === Proxy to Backend ===
location /api/ {
proxy_pass http://backend_upstream;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Connection pooling to upstream
proxy_set_header Connection "";
keepalive_timeout 60s;
}
# === Static files with CDN-friendly caching ===
location /static/ {
alias /var/www/example.com/static/;
expires 1y;
add_header Cache-Control "public, immutable";
add_header Vary "Accept-Encoding";
access_log off;
}
# === Gzip Compression ===
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
}
upstream backend_upstream {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
keepalive 32; # Connection pool size
}6. Code Example — Practical Scripts
6.1 Nginx Config with CDN Headers
# /etc/nginx/snippets/cdn-headers.conf
# Include này trong server block để support CDN caching
# Cho CDN biết cache bao lâu (CDN có thể cache lâu hơn browser)
# s-maxage: CDN cache time, max-age: browser cache time
add_header Cache-Control "public, s-maxage=86400, max-age=3600" always;
# Stale content: serve cũ trong 60s nếu origin lỗi
add_header Cache-Control "stale-while-revalidate=60, stale-if-error=86400" always;
# Cho CDN biết cache khác nhau theo Accept-Encoding (gzip vs br)
add_header Vary "Accept-Encoding" always;
# Cho biết response từ CDN hay origin
add_header X-Served-By $hostname always;
# CORS headers cho CDN assets
add_header Access-Control-Allow-Origin "*" always;
add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS" always;
add_header Access-Control-Max-Age "86400" always;
# Security headers
add_header X-Content-Type-Options "nosniff" always;6.2 DNS Health Check Script
#!/usr/bin/env bash
# dns-health-check.sh
# Kiểm tra DNS resolution health cho tất cả critical domains
# Chạy qua cron mỗi phút, alert nếu DNS fail
set -euo pipefail
# === Configuration ===
DOMAINS=(
"api.example.com"
"cdn.example.com"
"db-primary.internal.example.com"
"redis.internal.example.com"
)
DNS_SERVERS=("8.8.8.8" "1.1.1.1" "208.67.222.222")
TIMEOUT=5 # seconds
ALERT_WEBHOOK="${ALERT_WEBHOOK:-}" # Slack/PagerDuty webhook URL
LOG_FILE="/var/log/dns-health-check.log"
# === Functions ===
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}
send_alert() {
local message="$1"
if [[ -n "$ALERT_WEBHOOK" ]]; then
curl -s -X POST "$ALERT_WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{\"text\": \"DNS Health Check Alert: ${message}\"}" \
> /dev/null 2>&1
fi
log "ALERT: $message"
}
check_dns() {
local domain="$1"
local dns_server="$2"
local start end duration result
start=$(date +%s%N)
result=$(dig "@${dns_server}" "${domain}" A +short +time="${TIMEOUT}" +tries=1 2>/dev/null)
end=$(date +%s%N)
duration=$(( (end - start) / 1000000 )) # Convert to ms
if [[ -z "$result" ]]; then
echo "FAIL|${duration}|NO_RESULT"
return 1
fi
echo "OK|${duration}|${result}"
return 0
}
# === Main ===
log "--- DNS Health Check Started ---"
FAILURES=0
TOTAL=0
for domain in "${DOMAINS[@]}"; do
for dns_server in "${DNS_SERVERS[@]}"; do
TOTAL=$((TOTAL + 1))
output=$(check_dns "$domain" "$dns_server" || true)
status=$(echo "$output" | cut -d'|' -f1)
latency=$(echo "$output" | cut -d'|' -f2)
detail=$(echo "$output" | cut -d'|' -f3)
if [[ "$status" == "FAIL" ]]; then
FAILURES=$((FAILURES + 1))
send_alert "${domain} FAILED via ${dns_server} (${latency}ms): ${detail}"
elif [[ "$latency" -gt 200 ]]; then
log "SLOW: ${domain} via ${dns_server} = ${latency}ms (${detail})"
else
log "OK: ${domain} via ${dns_server} = ${latency}ms (${detail})"
fi
done
done
log "--- Completed: ${FAILURES}/${TOTAL} failures ---"
if [[ "$FAILURES" -gt 0 ]]; then
exit 1
fi6.3 Python: CDN Cache Hit Monitor
"""
CDN Cache Hit Ratio Monitor
Parse access logs và tính cache hit ratio real-time.
Alert nếu hit ratio drop dưới threshold.
"""
import re
import time
from collections import defaultdict
from dataclasses import dataclass, field
@dataclass
class CacheStats:
hits: int = 0
misses: int = 0
bypasses: int = 0
errors: int = 0
@property
def total(self) -> int:
return self.hits + self.misses + self.bypasses + self.errors
@property
def hit_ratio(self) -> float:
if self.total == 0:
return 0.0
return self.hits / self.total
def report(self) -> str:
return (
f"Total: {self.total:,} | "
f"HIT: {self.hits:,} ({self.hit_ratio:.1%}) | "
f"MISS: {self.misses:,} | "
f"BYPASS: {self.bypasses:,} | "
f"ERROR: {self.errors:,}"
)
@dataclass
class CDNCacheMonitor:
alert_threshold: float = 0.80 # Alert if hit ratio < 80%
stats_by_path: dict = field(default_factory=lambda: defaultdict(CacheStats))
global_stats: CacheStats = field(default_factory=CacheStats)
# Cloudflare log format pattern
LOG_PATTERN = re.compile(
r'(?P<ip>\S+) .+ "(?P<method>\S+) (?P<path>\S+) .+" '
r'(?P<status>\d+) .+ "(?P<cache_status>HIT|MISS|BYPASS|EXPIRED|DYNAMIC)"'
)
def process_line(self, line: str) -> None:
match = self.LOG_PATTERN.search(line)
if not match:
return
path = match.group("path")
cache_status = match.group("cache_status")
# Normalize path (remove query string)
base_path = path.split("?")[0]
# Update stats
if cache_status == "HIT":
self.global_stats.hits += 1
self.stats_by_path[base_path].hits += 1
elif cache_status in ("MISS", "EXPIRED"):
self.global_stats.misses += 1
self.stats_by_path[base_path].misses += 1
elif cache_status == "BYPASS":
self.global_stats.bypasses += 1
self.stats_by_path[base_path].bypasses += 1
else:
self.global_stats.errors += 1
self.stats_by_path[base_path].errors += 1
def check_alerts(self) -> list[str]:
alerts = []
if (self.global_stats.total > 100
and self.global_stats.hit_ratio < self.alert_threshold):
alerts.append(
f"ALERT: Global cache hit ratio {self.global_stats.hit_ratio:.1%} "
f"< threshold {self.alert_threshold:.1%}"
)
# Check per-path anomalies
for path, stats in self.stats_by_path.items():
if stats.total > 50 and stats.hit_ratio < 0.5:
alerts.append(
f"WARN: Path {path} has low hit ratio: {stats.hit_ratio:.1%} "
f"({stats.total} requests)"
)
return alerts
def top_misses(self, n: int = 10) -> list[tuple[str, CacheStats]]:
"""Paths với cache miss nhiều nhất — cần optimize"""
return sorted(
self.stats_by_path.items(),
key=lambda x: x[1].misses,
reverse=True
)[:n]
# === Usage ===
if __name__ == "__main__":
monitor = CDNCacheMonitor(alert_threshold=0.85)
# Simulate processing access log
sample_logs = [
'1.2.3.4 - - "GET /static/app.js HTTP/2" 200 1234 "HIT"',
'1.2.3.5 - - "GET /static/app.js HTTP/2" 200 1234 "HIT"',
'1.2.3.6 - - "GET /api/users HTTP/2" 200 567 "BYPASS"',
'1.2.3.7 - - "GET /static/logo.png HTTP/2" 200 89012 "MISS"',
'1.2.3.8 - - "GET /static/app.js HTTP/2" 200 1234 "HIT"',
]
for log_line in sample_logs:
monitor.process_line(log_line)
print("=== Global Stats ===")
print(monitor.global_stats.report())
print("\n=== Top Cache Misses ===")
for path, stats in monitor.top_misses(5):
print(f" {path}: {stats.report()}")
alerts = monitor.check_alerts()
if alerts:
print("\n=== ALERTS ===")
for alert in alerts:
print(f" {alert}")7. System Design Diagram — Full Request Lifecycle
sequenceDiagram participant User as Browser participant BCache as Browser Cache participant Resolver as DNS Resolver<br/>(8.8.8.8) participant Root as Root NS participant TLD as .com TLD NS participant Auth as Authoritative NS<br/>(ns1.example.com) participant CDN as CDN Edge<br/>(Singapore) participant Shield as Origin Shield<br/>(Tokyo) participant LB as Load Balancer participant Server as App Server Note over User,Server: Phase 1: DNS Resolution (~5-100ms) User->>BCache: Lookup api.example.com alt Browser cache HIT BCache-->>User: Cached IP (0ms) else Browser cache MISS User->>Resolver: Query api.example.com alt Resolver cache HIT Resolver-->>User: Cached IP (~5ms) else Resolver cache MISS Resolver->>Root: Query . (root) Root-->>Resolver: Refer to .com TLD Resolver->>TLD: Query .com TLD-->>Resolver: Refer to ns1.example.com Resolver->>Auth: Query api.example.com Auth-->>Resolver: A record: 93.184.216.34 (TTL=300) Resolver-->>User: 93.184.216.34 (~100ms total) end end Note over User,Server: Phase 2: TCP + TLS Handshake (~1-3 RTT) User->>CDN: TCP SYN CDN-->>User: SYN-ACK User->>CDN: ACK + TLS ClientHello CDN-->>User: TLS ServerHello + Cert + Finished User->>CDN: TLS Finished Note over User,Server: Phase 3: HTTP Request via CDN User->>CDN: GET /api/products (encrypted) alt CDN Cache HIT CDN-->>User: 200 OK + cached response (~30ms) else CDN Cache MISS CDN->>Shield: Forward request alt Origin Shield HIT Shield-->>CDN: Cached response else Origin Shield MISS Shield->>LB: Forward to origin LB->>Server: Route to healthy server Server-->>LB: Response LB-->>Shield: Response Shield-->>CDN: Response (cache for TTL) end CDN-->>User: 200 OK + response end Note over User,Server: Phase 4: Response Headers CDN-->>User: Cache-Control: public, max-age=3600<br/>CF-Cache-Status: HIT<br/>Strict-Transport-Security: max-age=63072000
Architecture Overview Diagram
flowchart TD subgraph "Client Layer" A["Browser / Mobile App"] A1["Browser DNS Cache<br/>Chrome: ~60s"] A2["OS DNS Cache<br/>macOS/Windows"] end subgraph "DNS Layer" B["Recursive Resolver<br/>(Cloudflare 1.1.1.1 / Google 8.8.8.8)"] B1["Root Name Servers<br/>(13 clusters worldwide)"] B2[".com TLD Servers"] B3["Authoritative NS<br/>(Route 53 / Cloudflare)"] end subgraph "CDN Layer" C["CDN Edge PoP<br/>(300+ locations)"] C1["Origin Shield<br/>(Regional cache)"] end subgraph "Infrastructure Layer" D["L4 Load Balancer<br/>(AWS NLB / HAProxy)"] E["L7 Load Balancer<br/>(AWS ALB / Nginx)"] F["WAF<br/>(Rate Limiting, DDoS Protection)"] end subgraph "Application Layer" G["App Server 1"] H["App Server 2"] I["App Server N"] end subgraph "Data Layer" J["Database<br/>(PostgreSQL)"] K["Cache<br/>(Redis)"] L["Object Storage<br/>(S3)"] end A --> A1 --> A2 --> B B --> B1 --> B2 --> B3 B3 -->|"IP of CDN Edge"| A A -->|"HTTPS Request"| C C -->|"Cache MISS"| C1 C1 -->|"Cache MISS"| F F --> D --> E E --> G & H & I G & H & I --> J & K G & H & I --> L C -->|"Cache HIT"| A C1 -->|"Cache HIT"| C style C fill:#4CAF50,stroke:#333,stroke-width:2px,color:white style C1 fill:#8BC34A,stroke:#333,stroke-width:2px style F fill:#FF5722,stroke:#333,stroke-width:2px,color:white style B fill:#2196F3,stroke:#333,stroke-width:2px,color:white
8. Aha Moments & Common Pitfalls
Aha Moments
#1 — DNS là single point of failure ẩn: Nếu DNS resolver chết → không ai access được website, dù server vẫn chạy tốt. Luôn dùng multiple NS records và multiple DNS providers (multi-DNS: Cloudflare + Route 53).
#2 — CDN không chỉ cho static files: Nhiều CDN hiện đại cache được API responses (Cloudflare Workers, CloudFront + Lambda@Edge). Với cache hit ratio 90%, CDN giảm 10 lần load lên origin server → trực tiếp giảm cost infrastructure.
#3 — TCP 3-way handshake + TLS = 2-3 RTT overhead: Đó là 300-450ms cho cross-region connection. Connection reuse (keep-alive, HTTP/2, connection pooling) là optimization quan trọng nhất cho latency.
#4 — HTTP/3 (QUIC) giải quyết head-of-line blocking: Đây là lý do Google, Facebook, Cloudflare đã adopt HTTP/3. Trên mobile (lossy network), HTTP/3 nhanh hơn HTTP/2 đáng kể vì packet loss không block tất cả streams.
#5 — CDN edge = security perimeter đầu tiên: CDN không chỉ cache — nó là tuyến phòng thủ DDoS. Cloudflare xử lý attack trước khi traffic đến origin. Origin server nên chỉ accept traffic từ CDN IPs.
#6 — DNS TTL là trade-off giữa performance và agility: TTL thấp = failover nhanh nhưng DNS traffic cao. TTL cao = DNS traffic thấp nhưng failover chậm. Không có one-size-fits-all — phải tune theo use case.
Common Pitfalls
Pitfall 1: DNS TTL quá cao trước migration
Sai: TTL = 86400s (1 ngày), rồi đổi IP server → user vẫn trỏ vào server cũ 24 giờ. Đúng: Hạ TTL xuống 60s ít nhất 48 giờ trước migration. Sau migration ổn định → tăng TTL lại.
Pitfall 2: DNS TTL quá thấp gây load
Sai: TTL = 10s cho tất cả records → DNS resolver phải query authoritative NS liên tục. Đúng: Chỉ hạ TTL cho records cần failover nhanh. Records ổn định (MX, TXT) giữ TTL cao (3600s+).
Pitfall 3: CDN Cache Stampede (Thundering Herd)
Sai: Tất cả CDN edge cùng cache expire → đồng loạt fetch từ origin → origin quá tải. Đúng: Dùng Origin Shield (request collapsing) + stale-while-revalidate (serve stale content trong khi background refresh) + jitter trong cache TTL.
# Thêm random jitter vào TTL để tránh stampede
Cache-Control: public, max-age=3600
# CDN config: add random 0-600s jitter → TTL thực tế = 3600-4200s
Pitfall 4: Mixed Content
Sai: Website HTTPS nhưng load images/scripts qua HTTP → browser block hoặc warning. Đúng: Tất cả resources phải HTTPS. Dùng
Content-Security-Policy: upgrade-insecure-requestsnhư safety net. Audit bằng browser DevTools → Console tab.
Pitfall 5: Không set Cache-Control headers đúng
Sai: Không set Cache-Control → CDN dùng default heuristic caching → content cũ bị serve quá lâu hoặc dynamic content bị cache. Đúng: Luôn explicit set Cache-Control cho mọi response:
- Static assets (immutable):
public, max-age=31536000, immutable- Dynamic HTML:
no-cache(revalidate mỗi request)- Private data (user-specific):
private, no-store- API responses:
public, s-maxage=60, max-age=0(CDN cache 60s, browser không cache)
Pitfall 6: Quên CNAME limitation ở apex domain
Sai: Đặt CNAME cho
example.com(root domain) → DNS violation, một số resolver reject. Đúng: Dùng A record hoặc ALIAS/ANAME record (nếu DNS provider support) cho root domain. CNAME chỉ cho subdomains (www,api,cdn).
Pitfall 7: Không restrict origin server access
Sai: Origin server accept traffic từ mọi IP → attacker bypass CDN, DDoS trực tiếp origin. Đúng: Origin firewall chỉ allow CDN IP ranges. Cloudflare publish IP ranges tại
https://www.cloudflare.com/ips/. AWS CloudFront dùng managed prefix list.
9. Quick Reference — Networking Numbers
DNS Latency Benchmarks
| Scenario | Latency |
|---|---|
| Browser DNS cache hit | 0ms |
| OS DNS cache hit | ~1ms |
| Resolver cache hit (same city) | ~5ms |
| Full recursive resolution | 50-200ms |
| DNSSEC validation overhead | +20-50ms |
| DNS over HTTPS (DoH) | +10-30ms |
CDN Provider Comparison
| Provider | Edge Locations | Free Tier | DDoS Protection | Best For |
|---|---|---|---|---|
| Cloudflare | 300+ | Generous | Included | General web, security-first |
| AWS CloudFront | 450+ | 1TB/month free | AWS Shield | AWS ecosystem |
| Google Cloud CDN | 150+ | None | Cloud Armor | GCP ecosystem |
| Akamai | 4100+ | None | Prolexic | Enterprise, media |
| Fastly | 80+ | Developer tier | Signal Sciences | Real-time purge, edge compute |
Protocol Decision Matrix
| Requirement | Protocol |
|---|---|
| Web API (CRUD) | HTTP/2 over TLS 1.3 |
| Real-time bidirectional | WebSocket over TLS |
| File upload/download | HTTP/2 + chunked transfer |
| Video streaming | HTTP/3 (QUIC) or HLS/DASH over HTTP/2 |
| DNS queries | UDP (< 512B) / TCP (> 512B) |
| Inter-service (low latency) | gRPC over HTTP/2 |
| IoT telemetry | MQTT over TLS / CoAP over DTLS |
| Online gaming | UDP + custom reliability layer |
10. Bài tập tự luyện
Bài 1: DNS Architecture cho Multi-region App
Scenario: App deploy ở 3 regions (US, EU, Asia). 50M DAU. Cần failover < 60s.
Thiết kế:
- DNS strategy (GeoDNS? Latency-based?)
- TTL settings cho từng record type
- Health check configuration
- Failover flow khi 1 region down
Bài 2: CDN Estimation cho E-commerce
Assumptions: 20M pageviews/day, avg page = 3MB (images heavy), 40% mobile users (smaller images), peak traffic = 5x average (flash sale).
Tính:
- Total bandwidth/day (peak)
- CDN cache hit ratio target
- Origin bandwidth với CDN
- Cost comparison: CDN vs no CDN
- Origin Shield sizing
Bài 3: TLS Performance Optimization
Scenario: API server handle 10K req/s, 80% clients are mobile (high latency ~100ms RTT).
Tính:
- Total TLS overhead/day (handshakes)
- Impact of TLS 1.2 → 1.3 upgrade
- Connection reuse ratio needed
- HTTP/2 vs HTTP/3 latency comparison
11. Internal Links — Navigation
| Tuần | Topic | Liên quan |
|---|---|---|
| Tuan-01-Scale-From-Zero-To-Millions | Scaling fundamentals | DNS, CDN là building blocks đầu tiên |
| Tuan-02-Back-of-the-envelope | Estimation | DNS latency, CDN bandwidth numbers |
| Tuan-04-API-Gateway | API Gateway | L7 routing, TLS termination |
| Tuan-05-Load-Balancer | Load Balancing | L4 vs L7 LB, connection pooling |
| Tuan-06-Cache-Strategy | Caching | CDN = edge cache, cache invalidation patterns |
| Tuan-09-Rate-Limiter | Rate Limiting | DDoS protection, DNS amplification defense |
| Tuan-11-Microservices | Microservices | mTLS, service mesh, internal DNS |
| Tuan-13-Monitoring-Observability | Monitoring | DNS health check, CDN hit ratio monitoring |
| Tuan-15-Data-Security-Encryption | Security | TLS cert management, DNSSEC, encryption |
Tham khảo
- Alex Xu, System Design Interview — Chapter 1: Scale from Zero to Millions (DNS, CDN sections)
- Cloudflare Learning Center — What is DNS?
- Cloudflare Learning Center — What is a CDN?
- Ilya Grigorik, High Performance Browser Networking — TCP, TLS, HTTP/2 chapters
- RFC 8446 — TLS 1.3 Specification
- RFC 9000 — QUIC Transport Protocol (HTTP/3)
- sdi.anhvy.dev — Vietnamese System Design Reference
- Tuan-02-Back-of-the-envelope — Estimation techniques dùng trong bài này
- Tuan-04-API-Gateway — Tiếp theo: API Gateway & TLS termination
- Tuan-05-Load-Balancer — L4 vs L7 Load Balancing deep dive
Tuần tới: Tuan-04-API-Gateway — API Gateway: routing, rate limiting, authentication tại edge