Telegraf机器人突发停止接收消息无报错问题求助
问题分析与解决方案
核心现象
- 基于Telegraf开发的请求接收Telegram机器人,稳定运行7个月后,近期(11月13日、12月2日)多次出现停止接收用户消息/指令的情况
- 机器人仍可正常发送回复给客户,Bot Token有效,无任何报错日志
- 每日约150个请求,对应生成150个Telegraf Wizard实例,仅能通过重启进程临时恢复
可能的原因及解决方法
1. 内存Session导致的资源耗尽
你的代码使用了Telegraf默认的内存session(bot.use(session());,注释掉了MongoDB存储),而Wizard场景依赖session维护用户会话状态。内存session不会自动清理过期会话,随着运行时间增加,内存占用持续上升,最终导致进程无法处理新请求。
解决方法:
- 启用MongoDB session存储,替换默认内存session:
// 初始化MongoDB session存储(需提前配置你的Mongo集合) const dbSessionStore = mongoSession({ collection: yourMongoCollection, }); // 替换原session中间件 bot.use(session({ store: dbSessionStore })); - 配置session过期时间,自动清理无效会话:
bot.use(session({ store: dbSessionStore, ttl: 86400 // 1天过期,可根据业务调整 }));
2. Long Polling连接异常(Telegraf默认模式)
Telegraf默认使用Long Polling与Telegram服务器保持连接,若网络波动、服务器连接超时或连接池耗尽,会导致机器人无法接收新更新,但仍能主动发送消息(主动发送是独立请求)。
解决方法:
- 切换到Webhook模式(生产环境推荐):
// 替换bot.launch()为Webhook配置 bot.launch({ webhook: { domain: '你的公网域名', port: 3000, // 自定义端口 path: '/webhook-path' } }); - 若坚持使用Long Polling,优化连接配置:
bot.launch({ polling: { timeout: 30, limit: 100, retryTimeout: 5000, allowedUpdates: ['message', 'edited_message'] // 只订阅需要的更新类型,降低负载 } });
3. 未捕获的Promise拒绝阻塞进程
外层try-catch无法捕获中间件(如Wizard场景、handleMessage)中的未处理Promise拒绝,这些错误会阻塞事件循环,导致机器人无法处理新请求,但不会触发进程崩溃(因此无报错日志)。
解决方法:
- 全局捕获未处理的Promise拒绝:
process.on('unhandledRejection', (reason, promise) => { console.error('未处理的Promise拒绝:', promise, '原因:', reason); }); - 给所有异步Handler添加错误捕获,例如修改
startHandler:export const startHandler = async function (ctx) { try { console.log('startHandler, ctx.scene', !!ctx.scene, 'ctx.wizard', !!ctx.wizard) await ctx.scene?.leave(); await ctx.scene?.enter('menuWizard'); } catch (e) { console.error('startHandler错误:', e); await ctx.reply('抱歉,出现了一些问题。'); } } - 给Wizard场景添加全局错误处理:
const menuWizard = new Scenes.WizardScene('menuWizard', ...menuWizardStages); menuWizard.use((ctx, next) => { return next().catch(err => { console.error('menuWizard错误:', err); ctx.reply('菜单操作出现错误。'); return ctx.scene.leave(); }); });
4. 进程资源耗尽
服务器CPU、内存或文件句柄耗尽,会导致机器人无法处理新请求。
解决方法:
- 使用pm2监控并自动重启进程:
# 启动进程并设置内存阈值,超过时自动重启 pm2 start 你的机器人脚本.js --name telegram-bot --max-memory-restart 200M # 查看实时监控 pm2 monit - 调整服务器资源限制(如文件句柄),修改
/etc/security/limits.conf:你的用户名 soft nofile 65535 你的用户名 hard nofile 65535
5. Telegram API相关排查
- 检查Webhook状态(若使用Webhook):调用
bot.telegram.getWebhookInfo()查看是否有错误 - 确认机器人未触发API请求限额:Telegram Bot API有频率限制,可通过日志或
bot.telegram.getMe()辅助排查 - 通过BotFather检查机器人是否因用户举报等原因受限
临时应急方案
在找到根本原因前,用pm2配置自动重启策略,减少人工干预:
pm2 start 你的机器人脚本.js --name telegram-bot --max-memory-restart 200M
内容的提问来源于stack exchange,提问作者Victor Gorban
相关产品推荐
相关产品推荐

