You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord Bot闲置1小时无活动自动停止问题排查(附源码)

Discord Bot 闲置1小时自动停止运行问题修复

核心原因

你用的discord.io是多年未维护的旧版本(当前依赖指向的是第三方修改的gateway v6兼容包),本身没有完善的WebSocket心跳保活和断连重连逻辑:Discord 网关要求客户端按固定间隔发送心跳包证明在线,闲置1小时左右没有有效心跳/交互就会主动断开连接,旧库没有处理断连重连,进程会直接退出。
另外你的代码里还有几个会直接触发进程崩溃、加剧断连的问题:

  • 自定义的sleep函数是do-while阻塞式实现,会完全卡住Node.js单线程事件循环,一旦阻塞时间刚好撞上心跳发送窗口,会直接被网关判定离线踢下线
  • 所有fs.readFileSync、fs.writeFile调用都没有做异常捕获,文件读写出错时会抛出未捕获异常,直接终止进程
  • 没有监听客户端断连事件、进程全局错误事件,出问题没有任何兜底恢复逻辑
  • 频繁在消息事件、editUser函数里用require()重复加载lore.json,require自带模块缓存,很容易读到旧数据,重复IO也会增加出错概率

具体修复步骤

  1. 先加断连重连和全局错误兜底,在bot初始化代码(new Discord.Client那段)后面追加以下代码:
// 网关断开后自动重连
bot.on('disconnect', () => {
  logger.warn('已与Discord网关断开连接,5秒后尝试重连')
  setTimeout(() => bot.connect(), 5000)
})

// 捕获全局未处理异常,避免进程直接崩溃
process.on('uncaughtException', (err) => {
  logger.error('触发未捕获异常:', err)
})
process.on('unhandledRejection', (reason) => {
  logger.error('触发未处理的Promise拒绝:', reason)
})
  1. 删掉整个阻塞式sleep函数,同时删掉editUser函数里的sleep(50)调用——Node.js是事件驱动的单线程 runtime,这种死循环式的sleep没有任何存在的意义,只会卡崩整个服务。
  2. 给所有文件读写操作加上错误处理,比如原来的无错误回调的writeFile改成:
fs.writeFile('./lore.json', JSON.stringify(data, null, 2), (err) => {
  if (err) logger.error('写入lore.json失败:', err)
})
  1. 去掉所有重复加载lore.json的代码:不要在每次收到消息、每次调用editUser的时候都require('./lore.json')或者readFileSync读文件,直接用启动时加载到内存的data变量即可,写入文件成功后内存里的data就是最新的,重复读文件只会增加不必要的IO开销和出错概率。
  2. 长期运行建议用进程守护工具托管,避免进程意外退出后无人重启:
    • 全局安装pm2:npm install -g pm2
    • 启动bot:pm2 start bot.js --name sage-lore-bot
    • 保存进程列表配置开机自启:pm2 startup && pm2 save

补充:discord.io已经停止维护多年,和当前Discord API版本的兼容性问题会越来越多,后续有空建议迁移到仍在活跃维护的Discord机器人库。

内容的提问来源于stack exchange,提问作者potato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 01:39:35