1. HTTP 代理负载均衡(使用 Flask 和 requests)
通过创建一个中间代理服务器,将请求分发给多个后端服务。
from flask import Flask, request
import requests
import random
app = Flask(__name__)
# 后端服务器列表
BACKENDS = [
"http://backend1.example.com",
"http://backend2.example.com",
"http://backend3.example.com",
]
# 简单的随机负载均衡
def get_backend():
return random.choice(BACKENDS)
@app.route("/<path:path>", methods=["GET", "POST"])
def proxy(path):
backend = get_backend()
url = f"{backend}/{path}"
try:
response = requests.request(
method=request.method,
url=url,
headers={k: v for k, v in request.headers if k.lower() != "host"},
data=request.get_data(),
cookies=request.cookies,
allow_redirects=False,
)
return (
response.content,
response.status_code,
dict(response.headers.items()),
)
except Exception as e:
return f"Error: {str(e)}", 500
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)
2. TCP 负载均衡(使用 asyncio)
基于异步 IO 实现 TCP 连接的负载均衡。
import asyncio
import random
# 后端服务器列表
BACKENDS = [
("backend1.example.com", 8080),
("backend2.example.com", 8080),
("backend3.example.com", 8080),
]
# 简单的随机负载均衡策略
def select_backend():
return random.choice(BACKENDS)
async def handle_client(client_reader, client_writer):
backend_addr = select_backend()
try:
# 连接后端服务器
backend_reader, backend_writer = await asyncio.open_connection(
*backend_addr
)
# 转发客户端数据到后端
async def client_to_backend():
while True:
data = await client_reader.read(4096)
if not data:
break
backend_writer.write(data)
await backend_writer.drain()
backend_writer.close()
# 转发后端数据到客户端
async def backend_to_client():
while True:
data = await backend_reader.read(4096)
if not data:
break
client_writer.write(data)
await client_writer.drain()
client_writer.close()
# 并发执行两个方向的转发
await asyncio.gather(client_to_backend(), backend_to_client())
except Exception as e:
print(f"Error: {e}")
finally:
client_writer.close()
async def main():
server = await asyncio.start_server(handle_client, "0.0.0.0", 8000)
async with server:
await server.serve_forever()
if __name__ == "__main__":
asyncio.run(main())
3. 使用第三方负载均衡库(如aioloadbalancer)
aioloadbalancer 是一个基于 asyncio 的 Python 负载均衡库,支持多种负载均衡策略。
from aioloadbalancer import LoadBalancer, Backend, RoundRobinStrategy
# 创建后端服务器
backends = [
Backend("http://backend1.example.com"),
Backend("http://backend2.example.com"),
Backend("http://backend3.example.com"),
]
# 使用轮询策略
strategy = RoundRobinStrategy()
lb = LoadBalancer(backends, strategy=strategy)
# 使用示例
async def fetch_data():
async with lb.get_session() as session:
async with session.get("/api/data") as response:
return await response.text()
4. 负载均衡策略
根据需求选择不同的负载均衡算法:
随机均衡(Random):随机选择后端服务器。
轮询(Round Robin):按顺序依次选择后端。
加权轮询(Weighted Round Robin):根据服务器性能分配权重。
IP 哈希(IP Hash):根据客户端 IP 地址计算哈希值,确保同一客户端始终路由到同一服务器。
最小连接数(Least Connections):选择当前连接数最少的服务器。
5. 健康检查
定期检查后端服务器的可用性,自动剔除不可用的节点:
import asyncio
import aiohttp
async def health_check(backend):
try:
async with aiohttp.ClientSession() as session:
async with session.get(f"{backend}/health") as response:
return response.status == 200
except:
return False
# 定期执行健康检查
async def monitor_backends(backends):
while True:
for backend in backends:
is_healthy = await health_check(backend)
backend.set_healthy(is_healthy)
await asyncio.sleep(30) # 每30秒检查一次
6. 实际应用场景
Web 服务负载均衡:将 HTTP 请求分发到多个 Web 服务器。
数据库连接池:在多个数据库实例之间平衡查询负载。
微服务架构:协调不同服务实例之间的请求流量。