Điểm duy nhất của ứng dụng bị lỗi sẽ giết chết. Khi máy chủ web duy nhất của bạn gặp sự cố, mọi người đều nhận được trang lỗi. Khi cơ sở dữ liệu của bạn ngừng hoạt động, toàn bộ ứng dụng của bạn sẽ ngừng hoạt động. Các kỹ thuật cân bằng tải và tính sẵn sàng cao sẽ phân phối lưu lượng truy cập và loại bỏ các điểm lỗi đơn lẻ này.
Điều kiện tiên quyết
- Hiểu biết về các nguyên tắc cơ bản của mạng và tường lửa
- Truy cập vào nhiều máy chủ hoặc container để thử nghiệm
- Kiến thức cấu hình máy chủ web cơ bản
Tại sao cân bằng tải lại quan trọng
Hãy bắt đầu với một ví dụ đơn giản. Bạn có một máy chủ web xử lý tất cả lưu lượng truy cập của mình:
Internet Users Single Web Server
│ │
┌────▼────┐ ┌────▼────┐
│ User 1 │ │ │
└─────────┘ │ nginx │
┌─────────┐ │ :80 │
│ User 2 │─────────────────►│ │
└─────────┘ │ CPU:95% │
┌─────────┐ │ Memory: │
│ User 3 │ │ 4GB/4GB │
└─────────┘ └─────────┘
┌─────────┐ │
│ User N │ ▼
└─────────┘ ❌ OVERLOADED
Khi lưu lượng truy cập tăng lên, máy chủ này sẽ trở nên quá tải. Cân bằng tải giải quyết vấn đề này bằng cách phân phối yêu cầu trên nhiều máy chủ:
Internet Users Load Balancer Backend Servers
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ User 1 │ │ │ │ nginx-1 │
└─────────┘ │ nginx │ │ :8080 │
┌─────────┐ │ LB │──────────────┤ CPU:30% │
│ User 2 │──────────────┤ :80 │ └─────────┘
└─────────┘ │ │ ┌─────────┐
┌─────────┐ │ Routes │──────────────│ nginx-2 │
│ User 3 │ │ Traffic │ │ :8080 │
└─────────┘ │ Evenly │ │ CPU:25% │
┌─────────┐ └─────────┘ └─────────┘
│ User N │ ┌─────────┐
└─────────┘ │ nginx-3 │
│ :8080 │
│ CPU:35% │
└─────────┘
Kiểm tra các kết nối hiện tại đến máy chủ của bạn:
# Check current connections to your server
netstat -an | grep :80 | grep ESTABLISHED | wc -l
Các loại cân bằng tải
Layer 4 (Lớp truyền tải): Phân phối dựa trên địa chỉ IP và cổng
# Client connects to load balancer IP:80
# Load balancer forwards to backend servers
# 192.168.1.10:80 → 10.0.1.100:8080
# 192.168.1.10:80 → 10.0.1.101:8080
Layer 7 (Lớp ứng dụng): Phân phối dựa trên nội dung như tiêu đề hoặc URL HTTP
# Route based on URL path
# /api/* → API servers (10.0.1.100-102)
# /static/* → Static file servers (10.0.2.100-102)
# /* → Web application servers (10.0.1.200-202)
Thiết lập cân bằng tải cơ bản
Cân bằng tải nginx
nginx tạo ra bộ cân bằng tải HTTP tuyệt vời. Đây là một cấu hình cơ bản:
# /etc/nginx/sites-available/load-balancer
upstream backend_servers {
server 10.0.1.100:8080;
server 10.0.1.101:8080;
server 10.0.1.102:8080;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://backend_servers;
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;
}
}
Kích hoạt và kiểm tra cấu hình:
# Enable the site
sudo ln -s /etc/nginx/sites-available/load-balancer \
/etc/nginx/sites-enabled/
# Test configuration
sudo nginx -t
# Reload nginx
sudo systemctl reload nginx
# Test load balancing
curl -H "Host: app.example.com" http://your-load-balancer
Cấu hình HAProxy
HAProxy cung cấp các tính năng cân bằng tải nâng cao hơn:
# /etc/haproxy/haproxy.cfg
global
daemon
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend web_frontend
bind *:80
default_backend web_servers
backend web_servers
balance roundrobin
option httpchk GET /health
server web1 10.0.1.100:8080 check
server web2 10.0.1.101:8080 check
server web3 10.0.1.102:8080 check
Bắt đầu HAProxy và kiểm tra:
# Test configuration
sudo haproxy -f /etc/haproxy/haproxy.cfg -c
# Start HAProxy
sudo systemctl start haproxy
# Check status
echo "show stat" | sudo socat stdio /var/lib/haproxy/stats
Thuật toán cân bằng tải
Các thuật toán khác nhau phân phối lưu lượng truy cập theo những cách khác nhau:
Vòng Robin
Yêu cầu đi đến từng máy chủ theo thứ tự:
upstream backend {
server server1.example.com;
server server2.example.com;
server server3.example.com;
}
Yêu cầu 1 → server1, Yêu cầu 2 → server2, Yêu cầu 3 → server3, Yêu cầu 4 → server1...
Robin vòng có trọng số
Một số máy chủ nhận được nhiều lưu lượng truy cập hơn:
upstream backend {
server server1.example.com weight=3;
server server2.example.com weight=2;
server server3.example.com weight=1;
}
Trong số 6 yêu cầu: 3 đến server1, 2 đến server2, 1 đến server3.
Ít kết nối nhất
Yêu cầu mới gửi đến máy chủ có ít kết nối hoạt động nhất:
upstream backend {
least_conn;
server server1.example.com;
server server2.example.com;
server server3.example.com;
}
Băm IP
Các yêu cầu từ cùng một IP luôn đến cùng một máy chủ:
upstream backend {
ip_hash;
server server1.example.com;
server server2.example.com;
server server3.example.com;
}
Điều này duy trì mối quan hệ phiên mà không yêu cầu lưu trữ phiên chia sẻ.
Kiểm tra sức khỏe
Bộ cân bằng tải chỉ nên gửi lưu lượng truy cập đến các máy chủ hoạt động tốt.
Kiểm tra tình trạng HTTP
Định cấu hình điểm cuối kiểm tra tình trạng trong ứng dụng của bạn:
# Simple health check endpoint
from flask import Flask, jsonify
import psycopg2
app = Flask(__name__)
@app.route('/health')
def health_check():
try:
# Check database connection
conn = psycopg2.connect(database_url)
cursor = conn.cursor()
cursor.execute('SELECT 1')
cursor.close()
conn.close()
return jsonify({'status': 'healthy'}), 200
except Exception as e:
return jsonify({'status': 'unhealthy', 'error': str(e)}), 503
Định cấu hình bộ cân bằng tải để sử dụng điểm cuối này:
upstream backend {
server 10.0.1.100:8080;
server 10.0.1.101:8080;
server 10.0.1.102:8080;
}
# nginx doesn't have built-in health checks in the free version
# Use nginx Plus or external monitoring
HAProxy đã tích hợp tính năng kiểm tra sức khỏe:
backend web_servers
option httpchk GET /health
http-check expect status 200
server web1 10.0.1.100:8080 check inter 5s
server web2 10.0.1.101:8080 check inter 5s
server web3 10.0.1.102:8080 check inter 5s
Kiểm tra tình trạng TCP
Đối với các dịch vụ không phải HTTP, hãy sử dụng kiểm tra tình trạng TCP:
backend database_servers
mode tcp
option tcp-check
server db1 10.0.1.200:5432 check port 5432
server db2 10.0.1.201:5432 check port 5432
Chấm dứt SSL
Bộ cân bằng tải có thể xử lý mã hóa SSL, giảm tải trên máy chủ backend.
Chấm dứt SSL tại Load Balancer
server {
listen 443 ssl http2;
server_name app.example.com;
ssl_certificate /etc/ssl/certs/app.example.com.crt;
ssl_certificate_key /etc/ssl/private/app.example.com.key;
# Modern SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
location / {
proxy_pass http://backend_servers;
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 https;
}
}
Truyền qua SSL
Đôi khi bạn muốn mã hóa đầu cuối:
stream {
upstream backend_ssl {
server 10.0.1.100:443;
server 10.0.1.101:443;
}
server {
listen 443;
proxy_pass backend_ssl;
proxy_ssl on;
}
}
Cơ sở dữ liệu có tính sẵn sàng cao
Cơ sở dữ liệu yêu cầu xem xét đặc biệt để có tính sẵn sàng cao.
Đọc bản sao
Phân phối các truy vấn đọc trên nhiều bản sao cơ sở dữ liệu:
# Database connection routing
import random
WRITE_DB = "postgresql://user:pass@primary-db:5432/app"
READ_DBS = [
"postgresql://user:pass@replica1-db:5432/app",
"postgresql://user:pass@replica2-db:5432/app",
"postgresql://user:pass@replica3-db:5432/app"
]
def get_db_connection(read_only=False):
if read_only:
return random.choice(READ_DBS)
else:
return WRITE_DB
Chuyển đổi dự phòng sơ cấp/thứ cấp
Triển khai chuyển đổi dự phòng tự động cho cơ sở dữ liệu ghi:
# PostgreSQL streaming replication setup
# Primary server: postgresql.conf
wal_level = replica
max_wal_senders = 3
wal_keep_segments = 64
# Secondary server: recovery.conf
standby_mode = 'on'
primary_conninfo = 'host=primary-db port=5432 user=replicator'
Sử dụng các công cụ như Patroni để tự động chuyển đổi dự phòng:
# patroni.yml
scope: postgres-cluster
name: postgres-node1
restapi:
listen: 0.0.0.0:8008
connect_address: 10.0.1.100:8008
postgresql:
listen: 0.0.0.0:5432
connect_address: 10.0.1.100:5432
data_dir: /var/lib/postgresql/data
bootstrap:
dcs:
postgresql:
parameters:
wal_level: replica
hot_standby: 'on'
max_wal_senders: 5
Cân bằng tải container
Môi trường container có những cân nhắc cân bằng tải riêng.
Cân bằng tải Docker Swarm
Docker Swarm cung cấp tính năng cân bằng tải tích hợp:
# Create a service with multiple replicas
docker service create --name web-service \
--replicas 3 \
--publish 80:8080 \
nginx
# Swarm automatically load balances between replicas
curl http://swarm-manager-ip
Dịch vụ Kubernetes
Dịch vụ Kubernetes cung cấp cân bằng tải cho pod:
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- port: 80
targetPort: 8080
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx
ports:
- containerPort: 8080
Triển khai và thử nghiệm:
# Apply configuration
kubectl apply -f web-service.yaml
# Check service status
kubectl get services
# Test load balancing
kubectl get endpoints web-service
Cân bằng tải toàn cầu
Đối với các ứng dụng có người dùng trên toàn thế giới, hãy phân phối lưu lượng truy cập theo địa lý.
Cân bằng tải toàn cầu dựa trên DNS
Sử dụng DNS để định tuyến người dùng đến trung tâm dữ liệu gần nhất:
# Route53 geolocation routing example
app.example.com A 54.230.1.1 # US East
app.example.com A 54.230.2.1 # US West
app.example.com A 54.230.3.1 # Europe
app.example.com A 54.230.4.1 # Asia
Cân bằng tải CDN
Mạng phân phối nội dung cung cấp cân bằng tải toàn cầu:
# CloudFlare configuration
# Users connect to nearest edge location
# Edge locations route to healthy origin servers
Giám sát hiệu suất cân bằng tải
Theo dõi các số liệu chính để đảm bảo cân bằng tải của bạn hoạt động hiệu quả.
Giám sát nginx
Kích hoạt mô-đun trạng thái nginx:
server {
listen 8080;
server_name localhost;
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
Kiểm tra trạng thái:
curl http://localhost:8080/nginx_status
Thống kê HAProxy
Kích hoạt trang thống kê HAProxy:
# Add to haproxy.cfg
listen stats
bind *:8404
stats enable
stats uri /stats
stats refresh 5s
stats admin if TRUE
Xem thống kê tại http://your-server:8404/stats
Số liệu ứng dụng
Giám sát số liệu cấp ứng dụng:
# Track requests per backend server
import time
from collections import defaultdict
request_counts = defaultdict(int)
response_times = defaultdict(list)
def track_request(server, response_time):
request_counts[server] += 1
response_times[server].append(response_time)
def get_stats():
return {
'request_counts': dict(request_counts),
'avg_response_times': {
server: sum(times) / len(times)
for server, times in response_times.items()
}
}
Khắc phục sự cố về cân bằng tải
Phân phối lưu lượng truy cập không đồng đều
Kiểm tra xem các yêu cầu có được phân bổ đồng đều hay không:
# Monitor backend server logs
tail -f /var/log/nginx/access.log | grep "backend_server_ip"
# Check connection counts per server
netstat -an | grep :8080 | grep ESTABLISHED | wc -l
Sự cố liên tục của phiên
Nếu người dùng đăng xuất ngẫu nhiên, dữ liệu phiên có thể không được chia sẻ:
# Solution 1: Use sticky sessions (ip_hash)
upstream backend {
ip_hash;
server server1.example.com;
server server2.example.com;
}
# Solution 2: Use shared session storage
# Configure Redis for session storage
Kiểm tra sức khỏe không thành công
Nếu máy chủ hoạt động tốt được đánh dấu là không hoạt động:
# Check health check endpoint manually
curl -I http://backend-server:8080/health
# Review health check configuration
# Ensure timeouts are appropriate for your application
Lập kế hoạch khắc phục thảm họa
Tính sẵn sàng cao vượt ra ngoài khả năng cân bằng tải để hoàn thành quá trình khắc phục thảm họa.
Triển khai đa khu vực
Triển khai ứng dụng trên nhiều vùng địa lý:
# Primary region: us-east-1
# Secondary region: us-west-2
# Tertiary region: eu-west-1
# DNS failover routes traffic to healthy regions
Sao chép dữ liệu
Đảm bảo dữ liệu được sao chép giữa các khu vực:
# Database replication
# File storage replication
# Configuration management
Chuyển đổi dự phòng tự động
Thực hiện các thủ tục chuyển đổi dự phòng tự động:
#!/bin/bash
# Simple failover script
PRIMARY_HEALTH_URL="http://primary.example.com/health"
SECONDARY_HEALTH_URL="http://secondary.example.com/health"
if ! curl -f $PRIMARY_HEALTH_URL; then
echo "Primary unhealthy, switching DNS to secondary"
# Update DNS records to point to secondary
aws route53 change-resource-record-sets --hosted-zone-id Z123 --change-batch file://failover.json
fi
Trong phần tiếp theo, chúng ta sẽ khám phá mạng container - cách Docker và Kubernetes xử lý cân bằng tải và khám phá dịch vụ trong môi trường được chứa trong container.
Cân bằng tải không chỉ đơn thuần là phân phối lưu lượng. Đó là việc tạo ra các hệ thống có khả năng phục hồi tốt, xử lý lỗi một cách khéo léo và cung cấp hiệu suất ổn định cho người dùng của bạn.
Chúc bạn cân bằng tải vui vẻ!