feat(reverse_ws): 添加反向WebSocket支持及负载均衡功能
- 新增反向WebSocket管理器模块,支持多客户端连接 - 实现负载均衡机制,自动选择健康且负载最低的客户端 - 添加防重复事件处理机制,防止消息重复处理 - 更新配置模型和加载器以支持反向WebSocket配置 - 添加示例文件和文档说明使用方法 - 修改主程序启动逻辑以支持反向WebSocket服务
This commit is contained in:
211
REVERSE_WS_LOAD_BALANCE.md
Normal file
211
REVERSE_WS_LOAD_BALANCE.md
Normal 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调用超时
|
||||
|
||||
**原因**:选择的客户端不健康或网络问题
|
||||
|
||||
**解决**:系统会自动切换到其他健康客户端
|
||||
|
||||
### 问题:所有客户端都不健康
|
||||
|
||||
**原因**:前端断开连接或网络问题
|
||||
|
||||
**解决**:检查前端连接状态和网络连接
|
||||
Reference in New Issue
Block a user