负载均衡是分布式系统的流量入口,将请求合理分配到后端服务器,提升系统吞吐与可用性。本文从基础算法到高级策略,全面解析负载均衡技术。
1. 负载均衡层次
| 层次 | 技术 | 特点 |
|---|---|---|
| DNS 层 | DNS 轮询、GeoDNS | 简单、成本低、TTL 延迟 |
| 网关层 | Nginx、HAProxy、ALB/CLB | 七层/四层、灵活 |
| 服务层 | Spring Cloud LB、Client-Side LB | 服务发现集成 |
| 应用层 | 自定义路由 | 业务逻辑驱动 |
2. 基础算法
2.1 轮询 (Round Robin)
class RoundRobinBalancer:
def __init__(self, servers):
self.servers = servers
self.index = 0
def get_server(self):
server = self.servers[self.index]
self.index = (self.index + 1) % len(self.servers)
return server
优点:绝对公平,实现简单
缺点:不考虑服务器负载差异
2.2 加权轮询 (Weighted Round Robin)
class WeightedRoundRobin:
def __init__(self, servers_with_weights):
# servers = [(server, weight), ...]
self.servers = []
for server, weight in servers_with_weights:
self.servers.extend([server] * weight)
self.index = 0
def get_server(self):
server = self.servers[self.index]
self.index = (self.index + 1) % len(self.servers)
return server
# 平滑加权轮询 (Nginx 算法)
class SmoothWeightedRoundRobin:
def __init__(self, servers):
self.servers = servers # [{server, weight, current}, ...]
self.total_weight = sum(s['weight'] for s in servers)
def get_server(self):
best = None
for s in self.servers:
s['current'] += s['weight']
if best is None or s['current'] > best['current']:
best = s
best['current'] -= self.total_weight
return best['server']
2.3 随机 (Random)
import random
def random_select(servers):
return random.choice(servers)
def weighted_random(servers_with_weights):
total = sum(w for _, w in servers_with_weights)
r = random.uniform(0, total)
cumulative = 0
for server, weight in servers_with_weights:
cumulative += weight
if r <= cumulative:
return server
2.4 最少连接 (Least Connections)
class LeastConnectionsBalancer:
def __init__(self, servers):
self.connections = {s: 0 for s in servers}
def get_server(self):
return min(self.connections, key=self.connections.get)
def acquire(self, server):
self.connections[server] += 1
def release(self, server):
self.connections[server] -= 1
适合长连接场景(WebSocket、TCP)。
2.5 IP Hash
def ip_hash_select(client_ip, servers):
return servers[hash(client_ip) % len(servers)]
同 IP 始终路由到同一服务器,适合会话保持。
2.6 一致性哈希负载均衡
from consistent_hashing import ConsistentHashRing
ch = ConsistentHashRing()
for server in servers:
ch.add_node(server)
def get_server(client_id):
return ch.get_node(client_id)
3. 健康检查
class HealthChecker:
def __init__(self, servers, interval=5):
self.servers = {s: {'healthy': True, 'last_check': 0} for s in servers}
self.interval = interval
def check(self, server):
try:
response = requests.get(f"http://{server}/health", timeout=2)
return response.status_code == 200
except:
return False
def get_healthy_servers(self):
now = time.time()
for server, status in self.servers.items():
if now - status['last_check'] > self.interval:
status['healthy'] = self.check(server)
status['last_check'] = now
return [s for s, v in self.servers.items() if v['healthy']]
4. Nginx 配置示例
upstream backend {
least_conn; # 最少连接
# ip_hash; # IP 哈希
# hash $request_id consistent; # 一致性哈希
server 10.0.0.1:8080 weight=5 max_fails=3 fail_timeout=30s;
server 10.0.0.2:8080 weight=3 backup; # 备用
server 10.0.0.3:8080 down; # 下线
keepalive 32;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_connect_timeout 2s;
proxy_next_upstream error timeout http_502 http_503;
}
}
5. LVS (Linux Virtual Server)
| 模式 | 特点 | 适用 |
|---|---|---|
| NAT | 修改 IP 地址 | 小规模 |
| DR (Direct Routing) | 直接路由,性能最高 | 大规模 |
| TUN (Tunneling) | IP 隧道,跨机房 | 异地多活 |
| FULLNAT | 修改源/目的 IP | 跨网段 |
总结
| 算法 | 适用场景 | 实现复杂度 |
|---|---|---|
| 轮询 | 服务器性能相同 | 低 |
| 加权轮询 | 服务器性能不同 | 低 |
| 最少连接 | 长连接、处理时间不均 | 中 |
| IP Hash | 会话保持 | 低 |
| 一致性哈希 | 缓存、有状态服务 | 中 |
| 自适应 | 动态负载变化 | 高 |
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。