负载均衡:流量分发与优化
负载均衡原理
负载均衡核心概念:
├── 负载均衡器: 分发流量的中间件
├── 后端服务器: 处理请求的服务实例
├── 健康检查: 检测后端服务状态
├── 会话保持: 维持用户会话
└── 故障转移: 自动切换故障节点
负载均衡算法
常见算法
algorithms:
round_robin:
description: "轮询"
algorithm: "依次将请求分发到每个服务器"
use_case: "服务器性能相同"
weighted_round_robin:
description: "加权轮询"
algorithm: "根据权重分配请求"
use_case: "服务器性能不同"
least_connections:
description: "最少连接"
algorithm: "将请求分发到连接数最少的服务器"
use_case: "长连接场景"
ip_hash:
description: "IP哈希"
algorithm: "根据客户端IP哈希选择服务器"
use_case: "需要会话保持"
least_response_time:
description: "最短响应时间"
algorithm: "将请求分发到响应最快的服务器"
use_case: "对延迟敏感"
Nginx负载均衡
基础配置
# nginx.conf
http {
upstream backend {
# 轮询(默认)
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080;
# 健康检查
server 10.0.0.1:8080 max_fails=3 fail_timeout=30s;
server 10.0.0.2:8080 max_fails=3 fail_timeout=30s;
# 备用服务器
server 10.0.0.4:8080 backup;
# 长连接
keepalive 32;
}
server {
listen 80;
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_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
# 故障转移
proxy_next_upstream error timeout http_502 http_503;
proxy_next_upstream_tries 3;
}
}
}
高级配置
# 加权轮询
upstream backend {
server 10.0.0.1:8080 weight=3;
server 10.0.0.2:8080 weight=2;
server 10.0.0.3:8080 weight=1;
}
# ip_hash(会话保持)
upstream backend {
ip_hash;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080;
}
# 最少连接
upstream backend {
least_conn;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080;
}
# 一致性哈希(基于请求URI)
upstream backend {
hash $request_uri consistent;
server 10.0.0.1:8080;
server 10.0.0.2:8080;
server 10.0.0.3:8080;
}
HAProxy配置
基础配置
# haproxy.cfg
global
maxconn 50000
log /dev/log local0
stats socket /var/run/haproxy.sock mode 660 level admin
defaults
mode http
timeout connect 5s
timeout client 60s
timeout server 60s
option httplog
option dontlognull
option http-server-close
option forwardfor
# HTTP前端
frontend http-in
bind *:80
bind *:443 ssl crt /etc/ssl/certs/haproxy.pem
redirect scheme https code 301 if !{ ssl_fc }
default_backend web-servers
# Web服务器后端
backend web-servers
balance roundrobin
option httpchk GET /health
http-check expect status 200
server web1 10.0.0.1:8080 check inter 5s fall 3 rise 2
server web2 10.0.0.2:8080 check inter 5s fall 3 rise 2
server web3 10.0.0.3:8080 check inter 5s fall 3 rise 2
# API后端
backend api-servers
balance leastconn
option httpchk GET /api/health
server api1 10.0.0.10:3000 check inter 5s
server api2 10.0.0.11:3000 check inter 5s
# 统计页面
listen stats
bind *:8404
stats enable
stats uri /stats
stats refresh 10s
stats auth admin:password
高级特性
# 会话保持
backend web-servers
balance roundrobin
cookie SERVERID insert indirect nocache
server web1 10.0.0.1:8080 check cookie web1
server web2 10.0.0.2:8080 check cookie web2
server web3 10.0.0.3:8080 check cookie web3
# 限流
frontend http-in
stick-table type ip size 100k expire 30s store http_req_rate(10s)
http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 }
# SSL终止
frontend https-in
bind *:443 ssl crt /etc/ssl/certs/haproxy.pem
ssl-default-bind-options ssl-min-ver TLSv1.2
云负载均衡
AWS ALB配置
# alb.tf
resource "aws_lb" "main" {
name = "main-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb.id]
subnets = var.public_subnet_ids
enable_deletion_protection = true
access_logs {
bucket = aws_s3_bucket.alb_logs.id
prefix = "alb"
enabled = true
}
}
resource "aws_lb_target_group" "app" {
name = "app-tg"
port = 80
protocol = "HTTP"
vpc_id = var.vpc_id
health_check {
enabled = true
healthy_threshold = 3
unhealthy_threshold = 3
timeout = 5
interval = 30
path = "/health"
matcher = "200"
}
}
resource "aws_lb_listener" "https" {
load_balancer_arn = aws_lb.main.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
certificate_arn = aws_acm_certificate.main.arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.app.arn
}
}
Kubernetes Ingress
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "5"
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: app-tls
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
监控和调优
负载均衡指标
# 关键监控指标
metrics:
connection_metrics:
- "active_connections"
- "connection_rate"
- "connection_errors"
request_metrics:
- "request_rate"
- "request_size"
- "response_size"
backend_metrics:
- "backend_health"
- "backend_response_time"
- "backend_error_rate"
system_metrics:
- "cpu_usage"
- "memory_usage"
- "network_throughput"
Prometheus监控配置
# prometheus-rules.yaml
groups:
- name: load-balancer
rules:
- alert: HighConnectionRate
expr: rate(haproxy_connections_total[5m]) > 10000
for: 5m
labels:
severity: warning
annotations:
summary: "连接率过高"
description: "当前连接率 {{ $value }}/s"
- alert: BackendDown
expr: haproxy_backend_active_servers < 1
for: 1m
labels:
severity: critical
annotations:
summary: "后端服务器全部宕机"
最佳实践
- 健康检查: 配置完善的健康检查机制
- 会话保持: 根据业务需求选择会话保持策略
- 故障转移: 配置自动故障转移和重试
- 限流: 实施请求限流保护后端服务
- 监控: 监控负载均衡器和后端服务状态
- 容量规划: 根据流量增长规划负载均衡容量