Files
NeoBot/REVERSE_WS_LOAD_BALANCE.md
K2cr2O1 014c6c9092 feat(reverse_ws): 添加反向WebSocket支持及负载均衡功能
- 新增反向WebSocket管理器模块,支持多客户端连接
- 实现负载均衡机制,自动选择健康且负载最低的客户端
- 添加防重复事件处理机制,防止消息重复处理
- 更新配置模型和加载器以支持反向WebSocket配置
- 添加示例文件和文档说明使用方法
- 修改主程序启动逻辑以支持反向WebSocket服务
2026-02-28 20:57:48 +08:00

5.1 KiB
Raw Blame History

反向 WebSocket 负载均衡配置

功能特性

1. 负载均衡

当有多个前端NapCat等连接到反向WebSocket服务端时系统会自动进行负载均衡

  • 自动选择负载最低的客户端API调用时会自动选择负载最低的健康客户端
  • 健康检查系统会记录每个客户端的最后活动时间只选择最近30秒内有活动的客户端
  • 负载计数:每个客户端的消息处理次数会被记录,用于负载均衡计算

2. 防重复发送

系统实现了多层防重复机制:

  • 事件ID检查通过事件IDidpost_idtime)识别重复事件
  • 消息锁机制:使用异步锁防止同一消息被并发处理
  • 双重检查:在锁内再次检查是否重复,防止并发竞争条件
  • 自动清理定期清理过期的事件ID和消息锁默认60秒和300秒

3. 工作原理

┌─────────────┐
│   Frontend  │
│   (NapCat)  │
└──────┬──────┘
       │
       │ WebSocket
       │
┌──────▼──────┐
│             │
│  ReverseWS  │ ←── 负载均衡 + 防重复
│  Manager    │
│             │
└──────┬──────┘
       │
       │ 处理事件
       │
┌──────▼──────┐
│  Command    │
│  Manager    │
│             │
└─────────────┘

配置说明

config.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 调用

使用负载均衡(推荐)

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
)

指定客户端

# 向特定客户端发送
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
)

获取客户端信息

# 获取所有连接的客户端
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 字段

消息锁

消息处理使用异步锁,防止并发重复处理:

async with self._get_message_lock(message_key):
    # 处理消息
    await matcher.handle_event(None, event)

自动清理

系统每10秒清理一次过期数据

  • 事件ID保留时间60秒
  • 消息锁保留时间300秒

监控和调试

查看客户端状态

# 查看所有客户端
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调用超时

原因:选择的客户端不健康或网络问题

解决:系统会自动切换到其他健康客户端

问题:所有客户端都不健康

原因:前端断开连接或网络问题

解决:检查前端连接状态和网络连接