feat(reverse_ws): 添加反向WebSocket支持及负载均衡功能

- 新增反向WebSocket管理器模块,支持多客户端连接
- 实现负载均衡机制,自动选择健康且负载最低的客户端
- 添加防重复事件处理机制,防止消息重复处理
- 更新配置模型和加载器以支持反向WebSocket配置
- 添加示例文件和文档说明使用方法
- 修改主程序启动逻辑以支持反向WebSocket服务
This commit is contained in:
2026-02-28 20:57:48 +08:00
parent ed4da64a7a
commit 014c6c9092
10 changed files with 769 additions and 6 deletions

211
REVERSE_WS_LOAD_BALANCE.md Normal file
View File

@@ -0,0 +1,211 @@
# 反向 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调用超时
**原因**:选择的客户端不健康或网络问题
**解决**:系统会自动切换到其他健康客户端
### 问题:所有客户端都不健康
**原因**:前端断开连接或网络问题
**解决**:检查前端连接状态和网络连接