Files
WechatHookBot/docs/控制台卡顿优化方案.md
2025-12-03 15:48:44 +08:00

4.9 KiB
Raw Blame History

WechatHookBot 控制台卡顿优化方案

问题判断

  • 控制台卡顿主要来源于高频日志输出、消息处理缺乏背压、插件耗时任务并发过高、异步调度开销叠加。
  • 项目当前在回调入口与路由层大量打印日志,并为每条消息创建异步任务,易导致 I/O 堆积与事件循环压力。
  • 关键日志位置:
    • 控制台与文件日志初始化:WechatHookBot/bot.py:236-249
    • 回调层日志:WechatHookBot/bot.py:49-78
    • 路由层日志:WechatHookBot/utils/hookbot.py:80-123

优化方案

日志优化

  • 将控制台日志级别降至 WARNING 或禁用控制台,仅保留文件日志;关闭 colorize 降低 Windows 终端渲染开销(参考 WechatHookBot/bot.py:236-241)。
  • 合并重复日志为一条结构化日志,减少每消息的 debug/info 输出;对系统与群成员变动事件保留必要日志,其余按采样输出(参考 WechatHookBot/bot.py:49-78WechatHookBot/utils/hookbot.py:80-123)。
  • 使用异步日志队列/缓冲写入降低主流程的 I/O 开销;缩短文件日志保留周期与大小(参考 WechatHookBot/bot.py:242-249)。

背压与队列

  • 在接收回调引入有界 asyncio.Queue(maxsize=...)on_receive 只负责快速入队,不对每条消息直接 run_coroutine_threadsafe(参考 WechatHookBot/bot.py:68-78)。
  • 由独立消费者协程从队列拉取并串行或受限并行处理;队列满时采用以下策略之一:
    • 丢弃最旧消息(防止饥饿)
    • 采样处理(降低负载)
    • 降级处理(仅计数、不分发事件)
  • 为高频消息类型设置优先级;在高水位时先处理高优先级(系统通知等),低优先级直接丢弃或延后。

并发与耗时任务

  • 使用 asyncio.Semaphore(n) 限制插件执行并发度,避免大量并行 I/O 或 CPU 任务压垮事件循环(事件分发位置:WechatHookBot/utils/hookbot.py:126-132)。
  • 为插件任务设置超时与熔断:单条消息处理超过阈值自动取消或降级;对连续失败触发短期熔断减少系统压力。

过滤策略

  • 启用/加强 ignore-mode:在群聊压力大时切换为 Whitelist 仅处理白名单来源;或用 Blacklist 屏蔽噪声(读取配置位置:WechatHookBot/utils/hookbot.py:33-50,过滤逻辑:WechatHookBot/utils/hookbot.py:160-171)。
  • 对非关键消息类型(除 11058 系统通知)在高负载状态下动态降级为统计计数,不逐条分发。

定时任务与调度

  • APScheduler 设置:
    • coalesce=True 合并触发
    • max_instances=1 防止并发堆积
    • 合理 misfire_grace_time
  • 将 APScheduler 相关日志降至 WARNING,避免定时任务导致控制台刷屏(启动点:WechatHookBot/bot.py:185-187)。

运行习惯与配置

  • 长期运行时仅启用文件日志或在初始化阶段保留控制台输出,稳定后自动关闭控制台 Sink。
  • 将日志采样率、队列容量、并发上限、忽略模式等参数放入 main_config.toml,支持运行期按需调整(配置读取:WechatHookBot/utils/hookbot.py:33-50)。

实施优先级

  1. 低风险配置级
    • 降低或关闭控制台日志、压低日志级别、关闭彩色输出、减少路由层细粒度日志。
  2. 架构级
    • 引入有界消息队列与单/多消费者;设置并发上限与任务超时;高水位时对低优先级消息降级或采样。
  3. 策略级
    • 启用白名单模式;扩充过滤类型;对高频事件采用采样与聚合日志。

验证要点

  • CPU 与终端响应度显著改善,logs/hookbot.log 保持必要信息且写入量合理。
  • 峰值时队列长度稳定在上限附近但不无限增长,平均处理时延可控。
  • 插件执行受限在设定并发与超时范围内,无明显阻塞主循环。

可配置建议示例(不直接改代码)

# main_config.toml 中建议新增
[Performance]
log_console_enabled = false         # 禁用控制台日志
log_level_file = "INFO"             # 文件日志级别
log_colorize = false                # 关闭彩色输出
log_sampling_rate = 0.1             # 日志采样比例10%

[Queue]
max_size = 1000                     # 消息队列容量
overflow_strategy = "drop_oldest"   # 溢出策略:丢弃最旧/采样/degrade

[Concurrency]
plugin_max_concurrency = 8          # 插件并发上限
plugin_task_timeout_seconds = 5     # 单任务超时

[Filter]
ignore_mode = "Whitelist"           # None/Whitelist/Blacklist
whitelist = ["room_wxid_xxx", "wxid_xxx"]
blacklist = []

[Scheduler]
coalesce = true
max_instances = 1
misfire_grace_time = 30

关联文件位置(便于落地)

  • 控制台与文件日志初始化:WechatHookBot/bot.py:236-249
  • 回调注册与消息接收:WechatHookBot/bot.py:42-83
  • 事件分发与过滤:WechatHookBot/utils/hookbot.py:68-132WechatHookBot/utils/hookbot.py:133-172
  • 定时任务启动:WechatHookBot/bot.py:185-187