1. Load Balancer là gì?
Load Balancer (LB) phân phối incoming traffic giữa nhiều server backend. Component này là trái tim của horizontal scaling — không có LB, scale ngang không khả thi.
5 chức năng chính:
- Distribute load — chia request giữa các backend.
- Health check — phát hiện backend chết, không gửi traffic đến.
- SSL termination — handle TLS, backend nhận HTTP plain.
- Failover — khi backend chết, chuyển traffic sang backend khác trong giây.
- Smart routing — route theo URL, header, geo, A/B test.
1.1. Vị trí trong kiến trúc
2. L4 vs L7 — hai tầng phân tải
"L4" và "L7" tham chiếu OSI layers (đã học ở Networking):
L4 Load Balancer (Transport)
Phân tải dựa trên thông tin TCP/UDP — IP và port nguồn/đích. KHÔNG hiểu HTTP.
- Ưu: cực nhanh, ít CPU, latency thấp; xử lý mọi protocol (HTTP, gRPC, WebSocket, custom TCP, UDP).
- Nhược: không thể route theo URL/header; không SSL termination tự nhiên (chỉ pass-through).
- Ví dụ: AWS NLB, HAProxy mode TCP, nginx stream module.
- Khi dùng: traffic non-HTTP (database proxy, gaming server, MQ); cần latency tối thiểu.
L7 Load Balancer (Application)
Phân tải dựa trên HTTP — URL path, header, cookie, body. Hiểu HTTP/HTTPS/HTTP2/gRPC.
- Ưu: smart routing (path, host, header), SSL termination, response caching, content modification, request retry, websocket upgrade.
- Nhược: chậm hơn L4 (parse HTTP), tốn CPU hơn.
- Ví dụ: AWS ALB, nginx, HAProxy mode HTTP, Envoy, Traefik, Kong.
- Khi dùng: web app, API; cần routing thông minh.
2.1. Có thể dùng cả hai
Pattern phổ biến: L4 ở edge → L7 phía sau. NLB nhận TLS terminate ở ALB phía sau cho phân tải HTTP-aware.
2.2. SSL termination
Client ──HTTPS──► [LB] ──HTTP──► Backend
▲
SSL terminate ở đây
(LB cầm cert, decrypt, forward)
Lợi: backend không tốn CPU encrypt/decrypt; quản lý cert ở 1 chỗ. Bảo mật: traffic LB→backend nội bộ thường an toàn (private network), nếu cần extra: SSL re-encryption (mTLS) tại LB.
3. Thuật toán phân tải
3.1. Round Robin
Quay vòng đều: req1 → server A, req2 → B, req3 → C, req4 → A...
Ưu: đơn giản, fair khi server đồng nhất.
Nhược: bỏ qua load thực tế. Server đang xử lý request "nặng" vẫn nhận thêm.
3.2. Weighted Round Robin
Mỗi server có weight, chia tỉ lệ. Server A weight 3, B weight 1 → A nhận 75% traffic.
Khi dùng: server có cấu hình khác nhau (mix giữa generation hardware), canary deploy.
3.3. Least Connections
Chọn server đang có ít active connection nhất.
Ưu: phản ánh load thực tế tốt hơn round robin.
Phù hợp: long-lived connection (WebSocket, long polling, streaming).
3.4. Least Response Time
Chọn server có latency average thấp nhất + ít connection.
Phức tạp hơn least conn; HAProxy có sẵn.
3.5. IP Hash / Source IP Hashing
Hash IP client → cùng IP luôn route đến cùng server. Dùng cho sticky session đơn giản.
Vấn đề: nhiều user share IP (NAT corporate, mobile carrier) → uneven distribution.
3.6. Consistent Hashing
Đã học ở Database (Ch10). Hash key (IP / userId / cache key) lên vòng tròn, mỗi server "sở hữu" 1 đoạn cung. Thêm/bớt server → chỉ ~1/N traffic redistribute.
Dùng cho: cache cluster (CloudFront, Memcached cluster), sharded service.
3.7. Random + Power of Two Choices
Pick 2 server random, chọn cái load thấp hơn. Đơn giản, gần optimal:
function pickBackend(backends: Backend[]) {
const a = backends[Math.floor(Math.random() * backends.length)];
const b = backends[Math.floor(Math.random() * backends.length)];
return a.activeConnections < b.activeConnections ? a : b;
}
Performance: với power-of-two-choices, max load expected là log(log(N)) thay vì log(N) như round robin. Used trong haproxy-2-choice mode, NetflixZuul.
3.8. So sánh thuật toán
| Algorithm | Khi tốt | Hạn chế |
|---|---|---|
| Round Robin | Server đồng nhất, request nhẹ tương đương nhau | Bỏ qua load thực |
| Weighted RR | Server khác cấu hình, canary | Vẫn không nhìn load thực |
| Least Connections | WebSocket, long polling, streaming | Cần track state global |
| IP Hash | Sticky đơn giản | NAT skew distribution |
| Consistent Hash | Cache cluster, sharded service | Phức tạp implement |
| P2C Random | Distributed, không cần state global | Random nhưng đủ tốt |
4. Health Check — phát hiện server chết
LB liên tục ping backend. Backend không response → đánh dấu unhealthy → ngừng route traffic.
4.1. Active vs Passive
- Active health check — LB chủ động ping định kỳ (mỗi 5-30s) đến endpoint
/health. Phổ biến nhất. - Passive health check — LB monitor real traffic, mark unhealthy khi error rate cao. Tiết kiệm tài nguyên hơn.
4.2. Endpoint /health design
// Liveness — chỉ check process còn sống
app.get('/health/live', (req, res) => {
res.status(200).json({ status: 'ok' });
});
// Readiness — sẵn sàng nhận traffic? (DB connect OK, cache warm)
app.get('/health/ready', async (req, res) => {
try {
await db.query('SELECT 1');
await redis.ping();
res.status(200).json({ status: 'ready' });
} catch (e) {
res.status(503).json({ status: 'not ready', error: e.message });
}
});
Phân biệt:
- Liveness — process có chạy không? Fail → restart (Kubernetes).
- Readiness — sẵn sàng nhận traffic? Fail → tạm thời không gửi traffic, KHÔNG restart.
4.3. Threshold
Tránh "flapping" (lúc up lúc down):
- Mark unhealthy: cần 2-3 fail liên tiếp.
- Mark healthy lại: cần 2-3 success liên tiếp.
4.4. Cascading failure
Vấn đề: khi 1 server unhealthy, LB chuyển traffic sang server còn lại → server còn lại quá tải → cũng unhealthy → toàn bộ chết.
Phòng tránh:
- Capacity dư — vận hành dưới 80% (đã học Ch1).
- Circuit breaker — cắt traffic đến server problematic chứ không "xóa".
- Slow start — server mới khôi phục nhận traffic từ từ, không 100% ngay.
5. Sticky Session
Pattern: cùng user luôn route đến cùng backend.
5.1. Cách triển khai
- Cookie-based — LB set cookie chứa server ID. Request kế tiếp có cookie → route đến đúng server.
- IP Hash — đã nói ở 3.5.
5.2. Khi nào cần?
Hiện đại: tránh sticky session nếu có thể. Pattern stateless tốt hơn nhiều:
- Session ở Redis/DB shared.
- Ai vào đâu cũng được — cluster horizontal scale tự nhiên.
Sticky chỉ cần khi:
- Migrate legacy app stateful.
- WebSocket — connection lâu, switch server giữa chừng phức tạp.
- In-memory state cho specific session (live game state).
5.3. Vấn đề sticky session
- Uneven load — user heavy hit cùng server.
- Server chết = session chết — fall back đến server khác mất state.
- Khó scale — auto-scale không hiệu quả nếu mỗi user "neo" vào 1 server.
Thực dụng: dùng JWT (stateless) cho auth → không cần sticky cho HTTP nhúng. Cho WebSocket: connection-pinning OK vì đã established.
6. Reverse Proxy vs Load Balancer
Hai khái niệm thường nhầm lẫn:
| Load Balancer | Reverse Proxy | |
|---|---|---|
| Định nghĩa | Phân phối traffic giữa nhiều backend | Đứng trước backend, nhận request thay backend |
| Yêu cầu nhiều backend? | Có (≥ 2) | Không (có thể 1) |
| Chức năng | Distribute, health check, failover | Caching, SSL termination, compression, request modification, security |
| Ví dụ | AWS ALB/NLB, F5 | nginx, Varnish, CloudFlare |
| Mối quan hệ | nginx có thể là CẢ HAI — reverse proxy + load balancer | |
Trong thực tế: nginx/Envoy thường vừa làm reverse proxy vừa làm L7 load balancer. Cùng 1 instance, cùng config.
6.1. Forward Proxy vs Reverse Proxy
- Forward Proxy — đứng trước CLIENT, ẩn client với server (như corporate proxy, VPN).
- Reverse Proxy — đứng trước SERVER, ẩn server với client.
7. nginx, HAProxy, Envoy — công cụ phổ biến
7.1. nginx
Reverse proxy + L7 LB phổ biến nhất. Event-driven (master/worker), C, cực nhanh.
# /etc/nginx/nginx.conf — basic LB setup
upstream backend {
least_conn; # algorithm
server backend1.example.com:8080 weight=3;
server backend2.example.com:8080 weight=1;
server backend3.example.com:8080 backup; # chỉ dùng khi cả 2 trên fail
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
location / {
proxy_pass http://backend;
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;
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
}
location /static {
proxy_pass http://backend;
proxy_cache static_cache;
proxy_cache_valid 200 1d; # cache response 200 trong 1 ngày
add_header X-Cache-Status $upstream_cache_status;
}
location /health {
return 200 "OK";
access_log off;
}
}
7.2. HAProxy
L4 + L7 LB, từ 2001. Đặc biệt mạnh cho TCP balancing, statistics phong phú.
frontend http-in
bind *:80
default_backend webservers
backend webservers
balance leastconn
option httpchk GET /health
server web1 10.0.0.1:8080 check inter 2000 rise 2 fall 3
server web2 10.0.0.2:8080 check inter 2000 rise 2 fall 3
server web3 10.0.0.3:8080 check inter 2000 rise 2 fall 3 weight 50
7.3. Envoy / Istio
Envoy = Lyft 2016, được CNCF. Modern data plane: gRPC native, observability tốt, hot reload không downtime.
Istio dùng Envoy làm sidecar trong service mesh — sẽ học Ch6.
7.4. Cloud LB
- AWS ELB — Classic LB (deprecated), ALB (L7), NLB (L4 ultra-fast), GLB (Global Accelerator).
- GCP — Cloud Load Balancer (global anycast).
- Cloudflare — Load Balancing trên edge.
- F5 / Citrix NetScaler — hardware enterprise, đắt.
Cloud managed LB tự autoscale, multi-AZ HA built-in. Trừ khi có lý do đặc biệt, dùng managed cho tiết kiệm vận hành.
8. Global Load Balancing
Load Balancer thông thường = trong 1 region. Khi user toàn cầu, cần Global LB để route đến region gần nhất.
8.1. DNS-based
Cách đơn giản: DNS resolve api.example.com trả IP khác nhau theo geo.
- User VN → IP của data center Singapore.
- User EU → IP của data center Frankfurt.
- User US → IP của data center Virginia.
Tools: AWS Route 53 (geolocation routing), Cloudflare Load Balancing (DNS-based).
Vấn đề: TTL DNS gây lag — failover region mất thời gian (TTL thường 5min).
8.2. Anycast
Cùng 1 IP công khai, nhưng được announce từ nhiều địa điểm địa lý qua BGP. Internet tự route đến địa điểm gần nhất.
Cloudflare, Google, AWS Global Accelerator dùng Anycast. Failover dưới giây — khi 1 region down, BGP tự withdraw route, traffic chuyển đến region khác.
8.3. CDN — Global LB cho static
CDN (CloudFront, Cloudflare, Fastly) là Global LB cho content cacheable. Sẽ chi tiết Ch7.
9. Patterns thực tế
9.1. Multi-tier LB
Mỗi tầng giải 1 vấn đề: edge (CDN/DDoS) → ingress (TLS, fast) → app routing (smart) → backend.
9.2. Blue-Green Deployment
2 environment giống nhau:
- Blue — production hiện tại.
- Green — version mới deploy.
Test green xong, switch LB từ blue → green. Sự cố? Switch back ngay.
9.3. Canary Deployment
Route 5% traffic đến version mới, 95% version cũ. Theo dõi metrics. OK → tăng dần đến 100%.
# Canary với weight:
upstream app {
server v1.app.local weight=95;
server v2.app.local weight=5;
}
9.4. A/B Testing
Tương tự canary nhưng split theo user (cookie/userId hash) để cùng user luôn thấy version giống nhau:
map $cookie_user_id $backend_version {
default v1;
"~*[0-9a-f]$" v2; # user_id ending in 0-9a-f → v2 (50%)
}
9.5. Geographic routing với fallback
Route theo geo, nhưng nếu region gần down → fallback sang region khác:
- Primary: VN user → ap-southeast-1.
- Fallback: ap-southeast-1 down → ap-northeast-1.
AWS Route 53 health check + geo routing làm tự động.
10. Bài tập
- So sánh L4 vs L7: cho 3 use case, mỗi cái nói nên dùng L4 hay L7 và lý do.
- (a) Database proxy cho 100 connection postgres
- (b) Web app với routing /api/v1, /api/v2 đến backend khác
- (c) Game server real-time UDP
- Setup nginx local làm reverse proxy + LB cho 3 Node.js app instance. Test với
abhoặck6. - Implement health check cho 1 service:
/health/live+/health/ready. Trong ready: check DB, Redis. Đảm bảo trả 503 khi DB down. - Phân biệt thuật toán cho 3 scenario:
- WebSocket app (connection lâu).
- Cache cluster với 4 node Redis.
- Stateless API CRUD bình thường.
- Setup Cloudflare DNS với load balancing: 2 region (US, EU), health check tự động fail over.
- Implement canary deployment với nginx: 5% traffic v2, 95% v1. Sau 1h mà không có error rate tăng → bump v2 lên 25%.
- Vì sao nên tránh sticky session khi có thể? Cho 2 alternative cụ thể.
11. Quiz
Quiz cuối Chương 2
L4 vs L7 Load Balancer khác chính ở:
Least Connections phù hợp NHẤT cho:
Liveness probe vs Readiness probe:
Sticky session nên TRÁNH khi có thể vì:
Consistent hashing thường dùng cho:
Anycast routing:
Cascading failure trong LB cluster:
Reverse Proxy vs Load Balancer:
Hoàn thành Chương 2. Tiếp theo: Chương 3 — Caching Strategies →