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也会增加出错概率
具体修复步骤
- 先加断连重连和全局错误兜底,在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) })
- 删掉整个阻塞式
sleep函数,同时删掉editUser函数里的sleep(50)调用——Node.js是事件驱动的单线程 runtime,这种死循环式的sleep没有任何存在的意义,只会卡崩整个服务。 - 给所有文件读写操作加上错误处理,比如原来的无错误回调的writeFile改成:
fs.writeFile('./lore.json', JSON.stringify(data, null, 2), (err) => { if (err) logger.error('写入lore.json失败:', err) })
- 去掉所有重复加载
lore.json的代码:不要在每次收到消息、每次调用editUser的时候都require('./lore.json')或者readFileSync读文件,直接用启动时加载到内存的data变量即可,写入文件成功后内存里的data就是最新的,重复读文件只会增加不必要的IO开销和出错概率。 - 长期运行建议用进程守护工具托管,避免进程意外退出后无人重启:
- 全局安装pm2:
npm install -g pm2 - 启动bot:
pm2 start bot.js --name sage-lore-bot - 保存进程列表配置开机自启:
pm2 startup && pm2 save
- 全局安装pm2:
补充:
discord.io已经停止维护多年,和当前Discord API版本的兼容性问题会越来越多,后续有空建议迁移到仍在活跃维护的Discord机器人库。
内容的提问来源于stack exchange,提问作者potato
相关产品推荐
相关产品推荐

