4.9 KiB
4.9 KiB
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-78、WechatHookBot/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)。
实施优先级
- 低风险配置级
- 降低或关闭控制台日志、压低日志级别、关闭彩色输出、减少路由层细粒度日志。
- 架构级
- 引入有界消息队列与单/多消费者;设置并发上限与任务超时;高水位时对低优先级消息降级或采样。
- 策略级
- 启用白名单模式;扩充过滤类型;对高频事件采用采样与聚合日志。
验证要点
- 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-132、WechatHookBot/utils/hookbot.py:133-172 - 定时任务启动:
WechatHookBot/bot.py:185-187