# 负载均衡功能 `ModifiableRequest` 类现在支持 round-robin 负载均衡功能,可以自动在多个后端服务器之间分发请求。 ## 功能特性 - 🔄 **Round-Robin 轮询**: 按顺序在多个主机之间分发请求 - 🛡️ **线程安全**: 使用锁机制确保并发安全 - 🔧 **灵活配置**: 支持带协议和不带协议的主机配置 - 🎯 **智能路由**: 自动判断是否需要负载均衡 ## 使用方法 ### 1. 基本负载均衡 ```python from pkg.dial import client from pkg.dial.req import ModifiableRequest def request_handler(request: ModifiableRequest): # 只指定路径,让负载均衡器自动选择主机 request.rewrite_uri("/api/users") return request.build() # 创建代理,支持多个后端服务器 proxy_handler = client.proxy( hosts=["server1.com", "server2.com", "server3.com"], req_fn=request_handler ) ``` ### 2. 带协议的主机配置 ```python # 支持混合协议配置 hosts = [ "http://server1.com", "https://server2.com", "server3.com" # 自动添加 http:// 前缀 ] proxy_handler = client.proxy(hosts, request_handler) ``` ### 3. 绕过负载均衡 ```python def request_handler_fixed(request: ModifiableRequest): # 指定完整 URL,绕过负载均衡 request.rewrite_uri("https://specific-server.com/api/users") return request.build() # 即使配置了多个主机,也会使用指定的 URL proxy_handler = client.proxy( hosts=["server1.com", "server2.com"], req_fn=request_handler_fixed ) ``` ## 工作原理 ### URL 解析逻辑 1. **检查 URL 是否包含主机**: - 如果 URL 包含主机(如 `https://example.com/api/users`),直接使用该 URL - 如果 URL 只有路径(如 `/api/users`),从主机列表中选择一个 2. **Round-Robin 选择**: - 使用线程安全的计数器 - 按顺序循环选择主机 - 自动处理主机数量变化 3. **URL 构建**: - 自动添加协议前缀(如果缺失) - 确保路径格式正确 - 合并查询参数 ### 示例请求分发 假设配置了 3 个主机:`["server1.com", "server2.com", "server3.com"]` ``` 请求 1: http://server1.com/api/users 请求 2: http://server2.com/api/users 请求 3: http://server3.com/api/users 请求 4: http://server1.com/api/users # 重新开始轮询 请求 5: http://server2.com/api/users ... ``` ## 配置示例 ### Starlette 应用中的使用 ```python from starlette.applications import Starlette from starlette.routing import Route from pkg.dial import client def api_handler(request: ModifiableRequest): request.rewrite_uri("/api/v1/data") return request.build() app = Starlette(routes=[ Route( "/api/data", client.proxy( hosts=[ "http://backend1:8080", "http://backend2:8080", "http://backend3:8080" ], req_fn=api_handler ) ) ]) ``` ### 健康检查集成 ```python def health_check_handler(request: ModifiableRequest): request.rewrite_uri("/health") return request.build() # 健康检查路由 health_proxy = client.proxy( hosts=["server1.com", "server2.com"], req_fn=health_check_handler ) ``` ## 注意事项 1. **主机格式**: 建议使用完整的主机名或 IP 地址 2. **协议处理**: 如果不指定协议,默认使用 `http://` 3. **并发安全**: 使用线程锁确保多线程环境下的安全性 4. **错误处理**: 如果主机列表为空,会抛出 `ValueError` 异常 5. **性能考虑**: 负载均衡器本身开销很小,适合高并发场景 ## 故障排除 ### 常见问题 1. **主机无法访问**: 确保所有配置的主机都是可访问的 2. **协议错误**: 检查主机配置中的协议是否正确 3. **路径问题**: 确保路径格式正确(以 `/` 开头) ### 调试技巧 ```python def debug_handler(request: ModifiableRequest): # 添加调试信息 request.add_header("X-Debug", "true") request.rewrite_uri("/api/debug") return request.build() ```