Giải Thích Load Balancing

Giới Thiệu
Khi ứng dụng của bạn bắt đầu nhận được nhiều traffic hơn khả năng xử lý của một máy chủ, bạn có hai lựa chọn: nâng cấp máy chủ mạnh hơn (vertical scaling) hoặc thêm nhiều máy chủ hơn (horizontal scaling). Load balancing chính là thứ giúp horizontal scaling trở nên khả thi.
Một load balancer phân phối traffic mạng đến nhiều máy chủ, đảm bảo không có máy chủ nào bị quá tải. Đây là một trong những thành phần quan trọng nhất của hạ tầng cho bất kỳ ứng dụng production nào — từ web app nhỏ đến hệ thống phục vụ hàng triệu người dùng.
Bài hướng dẫn này bao gồm mọi thứ bạn cần biết về load balancing: cách hoạt động, các thuật toán đằng sau nó, các loại khác nhau, và cách triển khai với các công cụ thực tế.
Bạn Sẽ Học Được Gì
✅ Hiểu load balancing là gì và tại sao nó quan trọng
✅ Nắm vững các thuật toán load balancing (Round Robin, Least Connections, IP Hash, và nhiều hơn nữa)
✅ Phân biệt giữa Layer 4 và Layer 7 load balancing
✅ Triển khai health check và failover cho high availability
✅ Cấu hình session persistence và SSL termination
✅ Thiết lập load balancing với Nginx, HAProxy, và cloud providers
✅ Tìm hiểu các mô hình như Active-Active, Active-Passive, và Global Server Load Balancing
Load Balancing Là Gì?
Load balancing là quá trình phân phối traffic mạng đến đến nhiều máy chủ backend (còn gọi là server pool hoặc server farm) để đảm bảo:
- Không có máy chủ nào bị quá tải với quá nhiều request
- Tính khả dụng của ứng dụng luôn cao ngay cả khi một máy chủ gặp sự cố
- Thời gian phản hồi luôn nhanh và ổn định cho tất cả người dùng
Không có load balancer, tất cả traffic đổ vào một máy chủ duy nhất:
1000 requests/giây → [Máy chủ duy nhất] → ❌ Quá tải, chậm, crashVới load balancer:
1000 requests/giây → [Load Balancer] → [Server 1] ~333 req/s ✅
→ [Server 2] ~333 req/s ✅
→ [Server 3] ~333 req/s ✅Tại Sao Cần Load Balancing?
Load balancing giải quyết nhiều vấn đề quan trọng:
| Lợi ích | Không có Load Balancer | Có Load Balancer |
|---|---|---|
| Tính khả dụng | Single point of failure | Vẫn hoạt động khi server gặp sự cố |
| Khả năng mở rộng | Giới hạn ở một server | Thêm server khi traffic tăng |
| Hiệu suất | Giảm dần khi tải tăng | Thời gian phản hồi ổn định |
| Bảo trì | Downtime khi cập nhật | Cập nhật cuốn chiếu không downtime |
| Hiệu quả | Server có thể quá tải hoặc nhàn rỗi | Phân phối đều công việc |
Các Thuật Toán Load Balancing
Thuật toán xác định cách load balancer quyết định server nào sẽ xử lý mỗi request đến. Các thuật toán khác nhau phù hợp với các tình huống khác nhau.
1. Round Robin
Thuật toán đơn giản nhất. Các request được phân phối tuần tự qua các server theo thứ tự.
Request 1 → Server 1
Request 2 → Server 2
Request 3 → Server 3
Request 4 → Server 1 (lặp lại chu kỳ)
Request 5 → Server 2
Request 6 → Server 3Cấu hình Nginx:
upstream backend {
server 192.168.1.101;
server 192.168.1.102;
server 192.168.1.103;
}
server {
location / {
proxy_pass http://backend;
}
}Phù hợp nhất cho: Các server có cấu hình giống nhau và ứng dụng stateless.
Nhược điểm: Không tính đến tải của server — một request xử lý chậm trên Server 1 không ngăn việc gửi thêm request đến nó.
2. Weighted Round Robin
Giống Round Robin nhưng gán nhiều request hơn cho server mạnh hơn.
Server 1 (weight=5): nhận 5 trong mỗi 8 request
Server 2 (weight=2): nhận 2 trong mỗi 8 request
Server 3 (weight=1): nhận 1 trong mỗi 8 requestCấu hình Nginx:
upstream backend {
server 192.168.1.101 weight=5; # 8-core, 32GB RAM
server 192.168.1.102 weight=2; # 4-core, 16GB RAM
server 192.168.1.103 weight=1; # 2-core, 8GB RAM
}Phù hợp nhất cho: Môi trường có các server với cấu hình khác nhau.
3. Least Connections
Gửi request đến server có ít kết nối active nhất.
Load balancer chọn Server 2 vì nó có ít kết nối active nhất.
Cấu hình Nginx:
upstream backend {
least_conn;
server 192.168.1.101;
server 192.168.1.102;
server 192.168.1.103;
}Phù hợp nhất cho: Ứng dụng có thời gian xử lý request khác nhau (ví dụ: một số request mất 50ms, số khác mất 5 giây).
4. Weighted Least Connections
Kết hợp Least Connections với trọng số server. Server có tỷ lệ (kết nối active / weight) thấp nhất sẽ nhận request tiếp theo.
Server 1: 10 kết nối, weight=5 → tỷ lệ = 2.0
Server 2: 3 kết nối, weight=2 → tỷ lệ = 1.5 ✅ (được chọn)
Server 3: 4 kết nối, weight=1 → tỷ lệ = 4.0Phù hợp nhất cho: Server có cấu hình khác nhau với thời gian xử lý request khác nhau.
5. IP Hash
Sử dụng địa chỉ IP của client để xác định server nào nhận request. Cùng một IP client luôn đến cùng một server.
Client 203.0.113.10 → hash → Server 2 (luôn luôn)
Client 198.51.100.5 → hash → Server 1 (luôn luôn)
Client 192.0.2.100 → hash → Server 3 (luôn luôn)Cấu hình Nginx:
upstream backend {
ip_hash;
server 192.168.1.101;
server 192.168.1.102;
server 192.168.1.103;
}Phù hợp nhất cho: Ứng dụng cần session persistence cơ bản mà không cần cookie hoặc quản lý session ở tầng ứng dụng.
Nhược điểm: Nếu một server bị down, tất cả client được hash đến server đó phải được phân phối lại, làm mất session của họ.
6. Least Response Time
Định tuyến đến server có thời gian phản hồi nhanh nhất và ít kết nối active nhất. Yêu cầu load balancer đo thời gian phản hồi một cách chủ động.
Phù hợp nhất cho: Ứng dụng yêu cầu hiệu suất cao, nơi bạn muốn người dùng được định tuyến đến server nhanh nhất.
7. Random
Chọn ngẫu nhiên một server cho mỗi request. Phân phối đều theo thống kê theo thời gian.
Phù hợp nhất cho: Pool server lớn, nơi sự đơn giản được ưu tiên và phân phối thống kê là đủ.
So Sánh Thuật Toán
| Thuật toán | Xét tải server | Session Persistence | Độ phức tạp | Trường hợp sử dụng tốt nhất |
|---|---|---|---|---|
| Round Robin | ❌ | ❌ | Thấp | Server giống nhau, app stateless |
| Weighted Round Robin | ❌ (weight thủ công) | ❌ | Thấp | Server cấu hình khác nhau |
| Least Connections | ✅ | ❌ | Trung bình | Thời gian xử lý request khác nhau |
| IP Hash | ❌ | ✅ | Thấp | Session affinity cơ bản |
| Least Response Time | ✅ | ❌ | Cao | App yêu cầu hiệu suất cao |
| Random | ❌ | ❌ | Thấp | Pool lớn, đơn giản |
Layer 4 vs Layer 7 Load Balancing
Load balancer hoạt động ở các tầng khác nhau của mô hình OSI. Hai tầng phổ biến nhất là Layer 4 (Transport) và Layer 7 (Application).
Layer 4 Load Balancing (Tầng Transport)
Hoạt động ở tầng TCP/UDP. Đưa ra quyết định định tuyến dựa trên:
- IP nguồn và port
- IP đích và port
- Giao thức (TCP hoặc UDP)
Load balancer không kiểm tra nội dung của request (không HTTP header, URL, hay cookie).
Cách hoạt động:
- Client thiết lập kết nối TCP đến load balancer
- Load balancer chọn một backend server (sử dụng thuật toán đã chọn)
- Load balancer chuyển tiếp các gói TCP/UDP thô đến server được chọn
- Tất cả gói tin từ cùng một kết nối đi đến cùng một server
Ưu điểm:
- Rất nhanh (không kiểm tra gói tin)
- Overhead và latency thấp
- Không phụ thuộc giao thức (hoạt động với HTTP, SMTP, FTP, database, v.v.)
Nhược điểm:
- Không thể định tuyến dựa trên URL, header, hoặc nội dung
- Không thể sửa đổi request hoặc response
- Khả năng health check hạn chế
Layer 7 Load Balancing (Tầng Application)
Hoạt động ở tầng HTTP/HTTPS. Đưa ra quyết định định tuyến dựa trên:
- Đường dẫn URL (ví dụ:
/api/*vs/static/*) - HTTP header (ví dụ:
Host,User-Agent,Cookie) - Phương thức HTTP (GET, POST, v.v.)
- Query parameter
- Nội dung body của request
Ví dụ định tuyến dựa trên nội dung với Nginx:
upstream api_servers {
server 192.168.1.101;
server 192.168.1.102;
}
upstream static_servers {
server 192.168.1.201;
server 192.168.1.202;
}
server {
listen 80;
location /api/ {
proxy_pass http://api_servers;
}
location /static/ {
proxy_pass http://static_servers;
}
location /images/ {
proxy_pass http://static_servers;
}
}Ưu điểm:
- Quyết định định tuyến nhận biết nội dung
- Có thể sửa đổi request/response (thêm header, viết lại URL)
- Health check nâng cao (HTTP status code, nội dung response)
- SSL termination
- Caching, nén, và rate limiting
Nhược điểm:
- Latency cao hơn (phải phân tích HTTP)
- Tốn tài nguyên hơn
- Chỉ HTTP/HTTPS (không phù hợp cho giao thức TCP tùy ý)
Bảng So Sánh
| Tính năng | Layer 4 | Layer 7 |
|---|---|---|
| Tầng OSI | Transport (TCP/UDP) | Application (HTTP/HTTPS) |
| Định tuyến dựa trên | IP, port, giao thức | URL, header, cookie, nội dung |
| Hiệu suất | Nhanh hơn (không kiểm tra) | Chậm hơn (phân tích HTTP) |
| Nhận biết nội dung | ❌ | ✅ |
| SSL Termination | Chỉ pass-through | ✅ Termination đầy đủ |
| Định tuyến URL | ❌ | ✅ |
| Thao tác Header | ❌ | ✅ |
| Caching | ❌ | ✅ |
| Giao thức | Mọi TCP/UDP | HTTP/HTTPS |
| Trường hợp sử dụng | Throughput cao, LB database | Web app, API, microservices |
Khi Nào Sử Dụng Loại Nào
Chọn Layer 4 khi:
- Bạn cần hiệu suất tối đa với latency tối thiểu
- Bạn load balancing các giao thức không phải HTTP (database, SMTP, gaming server)
- Bạn không cần định tuyến dựa trên nội dung
Chọn Layer 7 khi:
- Bạn cần định tuyến dựa trên URL path, header, hoặc cookie
- Bạn muốn SSL termination tại load balancer
- Bạn cần các tính năng nâng cao như caching, nén, hoặc rate limiting
- Bạn đang xây dựng microservices với các backend khác nhau cho các path khác nhau
Health Check và Failover
Load balancer phải biết server nào đang healthy và có khả năng xử lý request. Health check là các probe định kỳ gửi đến backend server để xác minh chúng đang hoạt động và chức năng bình thường.
Các Loại Health Check
1. TCP Health Check (Layer 4)
Đơn giản kiểm tra xem server có chấp nhận kết nối TCP trên port được chỉ định không.
Load Balancer → TCP SYN → Server:8080
Server:8080 → TCP SYN-ACK → ✅ Healthy2. HTTP Health Check (Layer 7)
Gửi một HTTP request đến health endpoint và kiểm tra response status code.
Load Balancer → GET /health → Server:8080
Server:8080 → 200 OK → ✅ Healthy
Server:8080 → 503 Service Unavailable → ❌ UnhealthyTriển khai health endpoint phổ biến:
// Express.js health check endpoint
app.get('/health', async (req, res) => {
try {
// Kiểm tra kết nối database
await db.query('SELECT 1');
// Kiểm tra kết nối Redis
await redis.ping();
res.status(200).json({
status: 'healthy',
uptime: process.uptime(),
timestamp: new Date().toISOString(),
});
} catch (error) {
res.status(503).json({
status: 'unhealthy',
error: error.message,
});
}
});// Spring Boot Actuator (health endpoint tự động cấu hình)
// GET /actuator/health → { "status": "UP" }
@Component
public class DatabaseHealthIndicator implements HealthIndicator {
@Override
public Health health() {
if (isDatabaseReachable()) {
return Health.up()
.withDetail("database", "PostgreSQL")
.build();
}
return Health.down()
.withDetail("error", "Cannot reach database")
.build();
}
}3. Script-based Health Check
Chạy script tùy chỉnh thực hiện các kiểm tra phức tạp (dung lượng ổ đĩa, bộ nhớ, logic ứng dụng).
Cấu Hình Health Check Nginx
upstream backend {
server 192.168.1.101;
server 192.168.1.102;
server 192.168.1.103;
# Passive health check (Nginx OSS)
# Đánh dấu server down sau 3 lần thất bại, thử lại sau 30 giây
}
server {
location / {
proxy_pass http://backend;
proxy_next_upstream error timeout http_500 http_502 http_503;
proxy_connect_timeout 5s;
proxy_read_timeout 10s;
}
}Cấu Hình Health Check HAProxy
backend web_servers
balance roundrobin
option httpchk GET /health
http-check expect status 200
server srv1 192.168.1.101:8080 check inter 5s fall 3 rise 2
server srv2 192.168.1.102:8080 check inter 5s fall 3 rise 2
server srv3 192.168.1.103:8080 check inter 5s fall 3 rise 2Giải thích các tham số:
inter 5s: Kiểm tra mỗi 5 giâyfall 3: Đánh dấu unhealthy sau 3 lần thất bại liên tiếprise 2: Đánh dấu healthy lại sau 2 lần thành công liên tiếp
Chiến Lược Failover
Khi một server không qua health check, load balancer phải xử lý:
Graceful degradation: Khi server gặp sự cố, các server còn lại gánh thêm tải:
Bình thường: Server A (33%) | Server B (33%) | Server C (33%)
Server C ❌: Server A (50%) | Server B (50%) | Server C (down)
Server B ❌: Server A (100%) | Server B (down) | Server C (down)Session Persistence (Sticky Sessions)
Mặc định, load balancer có thể định tuyến các request liên tiếp từ cùng một người dùng đến các server khác nhau. Đây là vấn đề khi ứng dụng lưu session data trong bộ nhớ server.
Vấn Đề
Request 1: User đăng nhập → Server A (session lưu trong bộ nhớ Server A)
Request 2: User tải dashboard → Server B (không tìm thấy session → ❌ chuyển hướng đến trang đăng nhập)Giải Pháp
1. Sticky Sessions (Dựa trên Cookie)
Load balancer chèn một cookie để gắn người dùng vào server cụ thể.
upstream backend {
server 192.168.1.101;
server 192.168.1.102;
# Nginx Plus (thương mại) sticky cookie
sticky cookie srv_id expires=1h domain=.example.com path=/;
}HAProxy sticky sessions:
backend web_servers
balance roundrobin
cookie SERVERID insert indirect nocache
server srv1 192.168.1.101:8080 cookie s1 check
server srv2 192.168.1.102:8080 cookie s2 check2. IP Hash (như đã thảo luận ở trên)
Định tuyến theo IP client — cùng một IP luôn đến cùng một server.
3. Externalized Sessions (Khuyến nghị)
Thay vì dựa vào sticky sessions, lưu session bên ngoài để bất kỳ server nào cũng có thể xử lý bất kỳ request nào:
// Express.js với Redis session store
import session from 'express-session';
import RedisStore from 'connect-redis';
import { createClient } from 'redis';
const redisClient = createClient({ url: 'redis://redis-host:6379' });
await redisClient.connect();
app.use(session({
store: new RedisStore({ client: redisClient }),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: { secure: true, maxAge: 86400000 }, // 24 giờ
}));Tại sao externalized sessions tốt hơn:
- Bất kỳ server nào cũng xử lý được bất kỳ request nào (stateless thực sự)
- Server gặp sự cố không mất session người dùng
- Dễ dàng mở rộng theo chiều ngang
- Không phức tạp sticky session
So Sánh Session Persistence
| Cách tiếp cận | Ảnh hưởng khi server lỗi | Khả năng mở rộng | Độ phức tạp |
|---|---|---|---|
| Sticky Sessions (Cookie) | Mất session khi server die | Hạn chế | Thấp |
| IP Hash | Mất session khi server die | Hạn chế | Thấp |
| External Store (Redis) | Không ảnh hưởng — session vẫn còn | Xuất sắc | Trung bình |
| JWT Token (Stateless) | Không ảnh hưởng — không có state trên server | Xuất sắc | Trung bình |
SSL/TLS Termination
SSL termination có nghĩa là load balancer xử lý việc mã hóa/giải mã traffic HTTPS, nên các backend server nhận HTTP thuần.
Tại Sao Terminate SSL Tại Load Balancer?
Lợi ích:
- Giảm tải server: Mã hóa/giải mã tốn CPU. Chuyển nó cho load balancer giải phóng backend server cho logic ứng dụng.
- Quản lý certificate tập trung: Quản lý SSL certificate ở một nơi thay vì mỗi server.
- Backend đơn giản hơn: Server không cần cấu hình SSL.
Nginx SSL termination:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://backend; # HTTP thuần đến backend
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
}
}SSL Pass-through vs Termination vs Re-encryption
| Chế độ | Mô tả | Backend nhận | Trường hợp sử dụng |
|---|---|---|---|
| Termination | LB giải mã, gửi HTTP đến backend | HTTP thuần | Hầu hết web application |
| Pass-through | LB chuyển tiếp traffic mã hóa nguyên bản | HTTPS (phải xử lý SSL) | Yêu cầu mã hóa end-to-end |
| Re-encryption | LB giải mã, sau đó mã hóa lại đến backend | HTTPS (mã hóa lại) | Yêu cầu compliance |
Các Load Balancer Phổ Biến
Software Load Balancer
1. Nginx
Web server và reverse proxy phổ biến nhất, cũng được sử dụng rộng rãi làm load balancer.
# Cấu hình load balancer Nginx hoàn chỉnh
upstream api_backend {
least_conn;
server 10.0.1.101:8080 weight=3;
server 10.0.1.102:8080 weight=2;
server 10.0.1.103:8080 weight=1;
server 10.0.1.104:8080 backup; # Chỉ dùng khi server khác down
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/ssl/certs/api.example.com.crt;
ssl_certificate_key /etc/ssl/private/api.example.com.key;
location / {
proxy_pass http://api_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;
# Timeout
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
proxy_send_timeout 30s;
# Thử lại khi thất bại
proxy_next_upstream error timeout http_502 http_503;
proxy_next_upstream_tries 3;
}
}Điểm mạnh: Nhẹ, hiệu suất cao, hệ sinh thái phong phú, tài liệu xuất sắc.
2. HAProxy
Load balancer TCP/HTTP hiệu suất cao, được thiết kế chuyên dụng.
# Cấu hình HAProxy
global
log stdout format raw local0
maxconn 4096
defaults
mode http
timeout connect 5s
timeout client 30s
timeout server 30s
option httplog
frontend http_front
bind *:80
bind *:443 ssl crt /etc/ssl/certs/example.pem
redirect scheme https if !{ ssl_fc }
# Định tuyến dựa trên URL path
acl is_api path_beg /api
acl is_static path_beg /static /images /css /js
use_backend api_servers if is_api
use_backend static_servers if is_static
default_backend web_servers
backend web_servers
balance roundrobin
option httpchk GET /health
http-check expect status 200
server web1 10.0.1.101:8080 check inter 5s fall 3 rise 2
server web2 10.0.1.102:8080 check inter 5s fall 3 rise 2
backend api_servers
balance leastconn
option httpchk GET /api/health
server api1 10.0.2.101:3000 check inter 5s fall 3 rise 2
server api2 10.0.2.102:3000 check inter 5s fall 3 rise 2
backend static_servers
balance roundrobin
server static1 10.0.3.101:80 check
server static2 10.0.3.102:80 checkĐiểm mạnh: Được xây dựng cho load balancing, dashboard thống kê xuất sắc, latency rất thấp, health check nâng cao, được GitHub, Stack Overflow, và Reddit sử dụng.
3. Traefik
Reverse proxy và load balancer hiện đại, cloud-native với khả năng tự động phát hiện dịch vụ.
# docker-compose.yml với Traefik
services:
traefik:
image: traefik:v3.0
command:
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "[email protected]"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- letsencrypt:/letsencrypt
api:
image: my-api:latest
deploy:
replicas: 3
labels:
- "traefik.http.routers.api.rule=Host(`api.example.com`)"
- "traefik.http.routers.api.tls.certresolver=letsencrypt"
- "traefik.http.services.api.loadbalancer.server.port=3000"
volumes:
letsencrypt:Điểm mạnh: Tự động phát hiện dịch vụ với Docker/Kubernetes, tích hợp Let's Encrypt sẵn có, cấu hình động không cần restart.
So Sánh Software Load Balancer
| Tính năng | Nginx | HAProxy | Traefik |
|---|---|---|---|
| Mục đích chính | Web server + LB | LB chuyên dụng | LB cloud-native |
| Layer 4 | ✅ | ✅ | ✅ |
| Layer 7 | ✅ | ✅ | ✅ |
| Cấu hình | File-based | File-based | File, Docker label, API |
| Tự phát hiện | ❌ (thủ công) | ❌ (thủ công) | ✅ (Docker, K8s) |
| Let's Encrypt | Qua certbot | Qua ACME | ✅ Tích hợp sẵn |
| Dashboard | Chỉ Nginx Plus | ✅ Trang stats | ✅ Web UI |
| Hot Reload | ✅ nginx -s reload | ✅ haproxy -sf | ✅ Tự động |
| Được dùng bởi | ~34% website | GitHub, Reddit | Tổ chức dùng Docker nhiều |
Cloud Load Balancer
Cloud provider cung cấp load balancer được quản lý, không cần quản lý server:
AWS:
- Application Load Balancer (ALB): Layer 7, định tuyến dựa trên nội dung, hỗ trợ WebSocket
- Network Load Balancer (NLB): Layer 4, latency cực thấp, hàng triệu request mỗi giây
- Classic Load Balancer (CLB): Legacy, hỗ trợ cả L4 và L7
Google Cloud:
- Cloud Load Balancing: Global, dựa trên anycast, tự động mở rộng, hỗ trợ HTTP(S), TCP, UDP
Azure:
- Azure Load Balancer: Layer 4
- Application Gateway: Layer 7 với WAF (Web Application Firewall)
Khi nào dùng cloud vs software load balancer:
| Tình huống | Khuyến nghị |
|---|---|
| Chạy trên một cloud provider | Dùng cloud LB (quản lý sẵn, tự mở rộng) |
| Multi-cloud hoặc hybrid | Software LB (Nginx, HAProxy) |
| Môi trường Kubernetes | Cloud LB + Ingress Controller (Nginx, Traefik) |
| Tiết kiệm chi phí, self-hosted | Nginx hoặc HAProxy trên VPS |
| Cần kiểm soát chi tiết | Software LB với cấu hình tùy chỉnh |
Load Balancing Trong Microservices
Trong kiến trúc microservices, load balancing trở nên càng quan trọng hơn khi các service liên tục giao tiếp với nhau.
Load Balancing Giữa Các Service
Client-Side vs Server-Side Load Balancing
Server-side load balancing (truyền thống): Một load balancer chuyên dụng nằm giữa các service.
Service A → Load Balancer → Service B (instance 1)
→ Service B (instance 2)
→ Service B (instance 3)Client-side load balancing: Service gọi tự chọn instance nào để gọi, sử dụng service registry.
Service A → [Service Registry] → biết tất cả instance của Service B
→ gọi trực tiếp Service B (instance 2)Ví dụ client-side (khái niệm):
class ClientSideLoadBalancer {
private instances: string[];
private currentIndex = 0;
constructor(private serviceRegistry: ServiceRegistry) {
this.instances = [];
}
async getNextInstance(serviceName: string): Promise<string> {
// Làm mới danh sách instance từ service registry
this.instances = await this.serviceRegistry.getInstances(serviceName);
if (this.instances.length === 0) {
throw new Error(`Không có instance nào cho ${serviceName}`);
}
// Round Robin
const instance = this.instances[this.currentIndex % this.instances.length];
this.currentIndex++;
return instance;
}
}Service Discovery
Để load balancing trong microservices, các service cần tìm thấy nhau. Đây gọi là service discovery.
DNS-based discovery:
# Kubernetes Service (DNS-based discovery tích hợp sẵn)
apiVersion: v1
kind: Service
metadata:
name: user-service
spec:
selector:
app: user-service
ports:
- port: 80
targetPort: 3000
type: ClusterIP
---
# Các service khác có thể gọi: http://user-service/api/users
# Kubernetes DNS phân giải đến các pod IP healthyRegistry-based discovery (Consul, Eureka, etcd):
Service B khởi động → đăng ký với Consul: "user-service tại 10.0.1.5:3000"
Service A cần Service B → hỏi Consul: "user-service ở đâu?"
Consul trả lời: ["10.0.1.5:3000", "10.0.1.6:3000", "10.0.1.7:3000"]
Service A chọn một → gọi 10.0.1.6:3000DNS-Based Load Balancing
DNS có thể thực hiện load balancing cơ bản bằng cách trả về các địa chỉ IP khác nhau cho cùng một tên miền.
Cách Hoạt Động
Client → DNS query: "api.example.com" → DNS server
DNS server → Response: [203.0.113.1, 203.0.113.2, 203.0.113.3]
Client → Kết nối đến 203.0.113.1 (thường là IP đầu tiên)Query tiếp theo (từ client khác hoặc cùng client, sau khi TTL hết hạn):
DNS server → Response: [203.0.113.2, 203.0.113.3, 203.0.113.1] (xoay vòng)Cấu Hình DNS Round Robin
; File zone DNS BIND
api.example.com. 300 IN A 203.0.113.1
api.example.com. 300 IN A 203.0.113.2
api.example.com. 300 IN A 203.0.113.3Hạn Chế Của DNS Load Balancing
| Hạn chế | Ảnh hưởng |
|---|---|
| DNS caching | Client và resolver cache response DNS. Thay đổi mất thời gian để lan truyền (dựa trên TTL). |
| Không có health check | DNS không biết server có down không. Client có thể kết nối đến server đã chết. |
| Không nhận biết session | Không kiểm soát được server nào xử lý client nào. |
| Phân phối không đều | Một số client cache lâu hơn, dẫn đến tải không đều. |
Khi nào DNS load balancing hữu ích:
- Phân phối traffic qua các vùng địa lý (GSLB)
- Là tầng đầu tiên trước load balancer chuyên dụng
- Setup đơn giản nơi health check không quan trọng
Global Server Load Balancing (GSLB)
GSLB phân phối traffic qua các server ở nhiều vị trí địa lý để giảm thiểu latency và cung cấp disaster recovery.
Cách GSLB Hoạt Động
- User thực hiện DNS query cho
app.example.com - DNS hỗ trợ GSLB xem xét:
- Vị trí địa lý của user
- Health của mỗi data center
- Tải hiện tại tại mỗi location
- Latency đến mỗi data center
- Trả về IP của data center gần nhất/tốt nhất
Chiến Lược Định Tuyến GSLB
| Chiến lược | Mô tả | Trường hợp sử dụng |
|---|---|---|
| Geolocation | Định tuyến theo quốc gia/vùng của client | Compliance, nội dung bản địa hóa |
| Latency-based | Định tuyến đến data center latency thấp nhất | Tối ưu hiệu suất |
| Failover | Data center chính/phụ | Disaster recovery |
| Weighted | Phân phối phần trăm traffic cho mỗi vùng | Di chuyển dần dần, canary deployment |
Dịch Vụ GSLB Cloud
- AWS Route 53: Latency-based, geolocation, failover, weighted routing
- Google Cloud DNS: Geolocation routing với health check
- Azure Traffic Manager: Performance, weighted, priority, geographic routing
- Cloudflare Load Balancing: Dựa trên anycast với geo-steering
Auto-Scaling Với Load Balancer
Load balancer kết hợp với auto-scaling để xử lý traffic spike tự động.
Cách Auto-Scaling Hoạt Động
Trigger mở rộng:
- CPU sử dụng > 70% trong 5 phút
- Bộ nhớ sử dụng > 80%
- Số request > 1000/giây mỗi server
- Thời gian phản hồi > 500ms trung bình
Kubernetes Horizontal Pod Autoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80AWS Auto Scaling Group
Load Balancer (ALB)
↓
Auto Scaling Group
├── Min: 2 instance
├── Desired: 3 instance
├── Max: 10 instance
└── Scaling Policy:
├── Scale Up: CPU > 70% trong 5 phút → thêm 2 instance
└── Scale Down: CPU < 30% trong 15 phút → bớt 1 instanceBest practice cho auto-scaling:
- Đặt ngưỡng scale-up thận trọng (phản ứng nhanh với traffic spike)
- Đặt ngưỡng scale-down tích cực (scale down chậm để tránh flapping)
- Luôn có số lượng instance healthy tối thiểu
- Sử dụng health check để đảm bảo instance mới sẵn sàng trước khi nhận traffic
Các Mô Hình Load Balancing
Active-Active
Tất cả server đều đang xử lý traffic đồng thời.
Load Balancer
├── Server A (Active) ← xử lý request
├── Server B (Active) ← xử lý request
└── Server C (Active) ← xử lý requestƯu điểm: Tận dụng tối đa tài nguyên, throughput cao nhất.
Nhược điểm: Tất cả server cần cấu hình giống nhau, phức tạp hơn để bảo trì.
Active-Passive (Failover)
Chỉ server active xử lý traffic. Server passive là standby, tiếp quản khi server active gặp sự cố.
Bình thường:
Load Balancer → Server A (Active) ← xử lý tất cả request
Server B (Passive/Standby) ← nhàn rỗi, giám sát
Failover:
Load Balancer → Server A (Down) ✗
Server B (Giờ là Active) ← tiếp quảnƯu điểm: Đơn giản, đảm bảo khả năng failover.
Nhược điểm: Server passive nhàn rỗi (lãng phí tài nguyên).
Blue-Green Deployment Với Load Balancer
Sử dụng load balancing để triển khai không downtime:
Bước 1: Blue (v1) đang live
Load Balancer → Blue Servers (v1) ✅
Bước 2: Deploy Green (v2), kiểm thử
Load Balancer → Blue Servers (v1) ✅
Green Servers (v2) [đang kiểm thử]
Bước 3: Chuyển traffic sang Green
Load Balancer → Green Servers (v2) ✅
Blue Servers (v1) [standby cho rollback]Canary Deployment
Định tuyến một tỷ lệ nhỏ traffic đến version mới:
upstream backend {
server 10.0.1.101:8080 weight=9; # v1 (90% traffic)
server 10.0.1.102:8080 weight=1; # v2 (10% traffic — canary)
}Tăng dần weight canary khi độ tin cậy tăng:
Giai đoạn 1: v1 = 90%, v2 = 10% → theo dõi metrics
Giai đoạn 2: v1 = 70%, v2 = 30% → theo dõi metrics
Giai đoạn 3: v1 = 50%, v2 = 50% → theo dõi metrics
Giai đoạn 4: v1 = 0%, v2 = 100% → rollout hoàn tấtGiám Sát và Metrics
Load balancer tạo ra các metrics giá trị để hiểu về health và hiệu suất hệ thống.
Các Metrics Quan Trọng Cần Giám Sát
| Metric | Cho biết điều gì | Ngưỡng cảnh báo |
|---|---|---|
| Request rate | Lượng traffic (req/s) | Tăng hoặc giảm đột ngột |
| Error rate | Tỷ lệ response 4xx/5xx | > 1% tổng traffic |
| Latency (p50, p95, p99) | Phân bố thời gian phản hồi | p99 > 1 giây |
| Active connections | Kết nối đồng thời hiện tại | Gần đến giới hạn server |
| Backend health | Số server healthy vs unhealthy | Bất kỳ server nào down |
| Bandwidth | Dữ liệu truyền vào/ra | Gần đến giới hạn mạng |
| Connection queue | Request đang chờ server | Queue > 0 kéo dài |
Giám Sát Nginx Status
# Bật Nginx stub status
server {
listen 8080;
location /nginx_status {
stub_status on;
allow 10.0.0.0/8; # Chỉ cho phép mạng nội bộ
deny all;
}
}# Output
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
Reading: 6 Writing: 179 Waiting: 106HAProxy Stats Dashboard
listen stats
bind *:8404
stats enable
stats uri /stats
stats refresh 10s
stats admin if TRUE
stats auth admin:passwordHAProxy cung cấp web dashboard tích hợp hiển thị metrics thời gian thực cho mỗi backend server: kết nối, tốc độ request, thời gian phản hồi, trạng thái health, và tỷ lệ lỗi.
Best Practices
Best Practice Cấu Hình
1. Luôn cấu hình health check
# Đừng chỉ kiểm tra port có mở không — kiểm tra health ứng dụng
location /health {
proxy_pass http://backend/health;
proxy_connect_timeout 2s;
proxy_read_timeout 2s;
}2. Đặt timeout phù hợp
proxy_connect_timeout 5s; # Thời gian thiết lập kết nối đến backend
proxy_read_timeout 30s; # Thời gian chờ response từ backend
proxy_send_timeout 10s; # Thời gian gửi request đến backend3. Truyền thông tin client đến 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;4. Cấu hình giới hạn kết nối
upstream backend {
server 192.168.1.101 max_conns=100;
server 192.168.1.102 max_conns=100;
queue 50 timeout=10s; # Xếp hàng request khi tất cả server đạt max
}Best Practice Kiến Trúc
1. Loại bỏ load balancer khỏi single point of failure
Sử dụng load balancer dự phòng với failover:
┌── Load Balancer 1 (Active)
Virtual IP ──┤
└── Load Balancer 2 (Standby)
│
┌───────┼───────┐
Server Server Server2. Sử dụng đúng thuật toán cho workload
- Stateless API: Round Robin hoặc Least Connections
- WebSocket connections: IP Hash hoặc Least Connections
- Server kích cỡ khác nhau: Weighted Round Robin
- Yêu cầu hiệu suất cao: Least Response Time
3. Externalize session state
Không dựa vào sticky sessions. Sử dụng Redis, Memcached, hoặc JWT token cho quản lý session.
4. Bật connection keep-alive
upstream backend {
server 192.168.1.101;
keepalive 32; # Giữ 32 kết nối idle cho mỗi backend
}
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection ""; # Bật keepalive đến backend
}5. Lên kế hoạch graceful shutdown
Khi gỡ server để bảo trì:
1. Đánh dấu server "draining" (ngừng kết nối mới)
2. Chờ các kết nối hiện tại hoàn thành
3. Gỡ server khỏi pool
4. Thực hiện bảo trì
5. Thêm lại server vào pool
6. Giám sát health check xác nhận nó healthyCác Lỗi Thường Gặp
| Lỗi | Vấn đề | Giải pháp |
|---|---|---|
| Không có health check | Traffic gửi đến server đã chết | Luôn cấu hình health endpoint |
| Load balancer đơn | LB trở thành single point of failure | Deploy LB dự phòng với failover |
| Sticky sessions khắp nơi | Hạn chế khả năng mở rộng, failover phức tạp | Dùng external session store (Redis) |
| Bỏ qua timeout | Backend chậm block tất cả kết nối | Đặt connect, read, và send timeout |
| Không giám sát | Vấn đề được phát hiện bởi user, không phải engineer | Giám sát request rate, error, latency |
| Cấu hình SSL sai | Mixed content, cảnh báo bảo mật | Terminate SSL tại LB, redirect HTTP sang HTTPS |
| Không giới hạn kết nối | Một backend bị quá tải do burst | Đặt max_conns cho mỗi server |
| Không graceful shutdown | Request active bị drop khi deploy | Drain kết nối trước khi gỡ server |
Tóm Tắt và Điểm Chính
✅ Load balancing phân phối traffic qua nhiều server cho khả năng mở rộng, tính khả dụng, và hiệu suất
✅ Thuật toán như Round Robin, Least Connections, và IP Hash xác định cách traffic được định tuyến
✅ Layer 4 load balancing nhanh hơn nhưng không nhận biết nội dung; Layer 7 cho phép định tuyến dựa trên URL, header, và cookie
✅ Health check là thiết yếu — luôn cấu hình để phát hiện và gỡ bỏ server unhealthy
✅ Externalize session state (Redis, JWT) thay vì dựa vào sticky sessions
✅ SSL termination tại load balancer đơn giản hóa quản lý certificate và giảm tải backend
✅ Nginx và HAProxy là software load balancer phổ biến nhất; cloud provider cung cấp giải pháp managed
✅ Auto-scaling kết hợp với load balancer để xử lý traffic spike tự động
✅ Giám sát request rate, error rate, latency, và backend health liên tục
✅ Deploy load balancer dự phòng để tránh single point of failure
Tiếp Theo
Bây giờ bạn đã hiểu load balancing, hãy khám phá các chủ đề liên quan:
- Giải Thích Reverse Proxy — Tìm hiểu reverse proxy hoạt động như thế nào và liên quan đến load balancer ra sao
- Hướng Dẫn Toàn Diện HTTP Protocol — Deep dive vào giao thức mà load balancer định tuyến
- Giải Thích Kiến Trúc Client-Server — Hiểu nền tảng mà load balancing xây dựng trên đó
Load balancing là một trong những quyết định hạ tầng có ảnh hưởng lớn nhất mà bạn sẽ đưa ra. Bắt đầu với setup Round Robin đơn giản, thêm health check, externalize session, và mở rộng từ đó. Bạn không cần triển khai mọi thứ ngay ngày đầu — nhưng bạn cần lên kế hoạch cho nó.
📬 Đăng ký nhận bản tin
Nhận những bài viết mới nhất qua email mỗi tuần. Không spam, hủy đăng ký bất cứ lúc nào.
Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất cứ lúc nào.
💬 Comments
Đăng nhập để bình luận
Chúng tôi sẽ không đăng bất cứ điều gì mà không có sự cho phép của bạn.