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 服务器。
数据库连接池:在多个数据库实例之间平衡查询负载。
微服务架构:协调不同服务实例之间的请求流量。