# 反向 WebSocket 负载均衡配置 ## 功能特性 ### 1. 负载均衡 当有多个前端(NapCat等)连接到反向WebSocket服务端时,系统会自动进行负载均衡: - **自动选择负载最低的客户端**:API调用时会自动选择负载最低的健康客户端 - **健康检查**:系统会记录每个客户端的最后活动时间,只选择最近30秒内有活动的客户端 - **负载计数**:每个客户端的消息处理次数会被记录,用于负载均衡计算 ### 2. 防重复发送 系统实现了多层防重复机制: - **事件ID检查**:通过事件ID(`id`、`post_id`或`time`)识别重复事件 - **消息锁机制**:使用异步锁防止同一消息被并发处理 - **双重检查**:在锁内再次检查是否重复,防止并发竞争条件 - **自动清理**:定期清理过期的事件ID和消息锁(默认60秒和300秒) ### 3. 工作原理 ``` ┌─────────────┐ │ Frontend │ │ (NapCat) │ └──────┬──────┘ │ │ WebSocket │ ┌──────▼──────┐ │ │ │ ReverseWS │ ←── 负载均衡 + 防重复 │ Manager │ │ │ └──────┬──────┘ │ │ 处理事件 │ ┌──────▼──────┐ │ Command │ │ Manager │ │ │ └─────────────┘ ``` ## 配置说明 在 `config.toml` 中配置: ```toml [reverse_ws] enabled = true # 启用反向WebSocket host = "0.0.0.0" # 监听地址 port = 3002 # 监听端口 token = "" # 访问令牌(可选) ``` ## 使用方法 ### 启动配置 1. 在 `config.toml` 中设置 `enabled = true` 2. 确保防火墙允许指定端口的连接 3. 启动机器人服务 ### 前端配置 在 NapCat 等前端配置中,将 WebSocket 连接地址改为: ``` ws://your-server-ip:3002 ``` 多个前端可以连接到同一个地址,系统会自动进行负载均衡。 ## API 调用 ### 使用负载均衡(推荐) ```python from core.managers import reverse_ws_manager # 自动选择负载最低的健康客户端 response = await reverse_ws_manager.call_api( action="send_group_msg", params={ "group_id": 123456, "message": "Hello" }, use_load_balance=True # 默认为 True ) ``` ### 指定客户端 ```python # 向特定客户端发送 response = await reverse_ws_manager.call_api( action="send_group_msg", params={ "group_id": 123456, "message": "Hello" }, client_id="specific-client-id", use_load_balance=False ) ``` ### 获取客户端信息 ```python # 获取所有连接的客户端 clients = reverse_ws_manager.get_connected_clients() # 获取健康的客户端(最近30秒有活动) healthy = reverse_ws_manager.get_healthy_clients() # 获取负载最低的客户端 least_load = reverse_ws_manager.get_client_with_least_load() ``` ## 负载均衡策略 系统采用以下策略选择客户端: 1. **健康检查**:只选择最近30秒内有活动的客户端 2. **负载计数**:在健康客户端中选择负载最低的 3. **自动切换**:如果负载最低的客户端不健康,自动选择下一个 ## 防重复机制 ### 事件ID检查 系统通过以下方式识别事件: - 优先使用 `id` 字段 - 其次使用 `post_id` 字段 - 最后使用 `time` 字段 ### 消息锁 消息处理使用异步锁,防止并发重复处理: ```python async with self._get_message_lock(message_key): # 处理消息 await matcher.handle_event(None, event) ``` ### 自动清理 系统每10秒清理一次过期数据: - 事件ID保留时间:60秒 - 消息锁保留时间:300秒 ## 监控和调试 ### 查看客户端状态 ```python # 查看所有客户端 print("所有客户端:", reverse_ws_manager.get_connected_clients()) # 查看健康客户端 print("健康客户端:", reverse_ws_manager.get_healthy_clients()) # 查看负载情况 print("客户端负载:", reverse_ws_manager._client_load) # 查看健康时间 print("客户端健康时间:", reverse_ws_manager._client_health) ``` ### 日志输出 系统会输出以下日志: - 客户端连接/断开 - 检测到重复事件 - 负载均衡选择 - API调用结果 ## 最佳实践 1. **多前端部署**:建议部署2-3个前端实例进行负载均衡 2. **健康检查**:定期检查前端连接状态 3. **监控日志**:关注重复事件日志,排查网络问题 4. **合理设置TTL**:根据消息频率调整事件ID保留时间 ## 故障排查 ### 问题:消息重复处理 **原因**:网络延迟导致前端重复发送 **解决**:检查事件ID是否正确设置,系统已自动处理 ### 问题:API调用超时 **原因**:选择的客户端不健康或网络问题 **解决**:系统会自动切换到其他健康客户端 ### 问题:所有客户端都不健康 **原因**:前端断开连接或网络问题 **解决**:检查前端连接状态和网络连接