pyTelegramBotAPI无法同时处理3个及以上消息问题排查
Telegram Bot无法处理第三条及以上消息的问题排查与解决
问题描述
我正在开发一款Telegram Bot,需同时处理多条消息。Bot的消息处理函数捕获消息后会运行数小时,执行发送定时HTTP请求、处理数据等操作。但发送3条及以上触发该函数的消息时,仅前两条能正常处理,后续消息均被忽略。
相关代码
import os, time import telebot import logging logging.basicConfig(filename='example.log', encoding='utf-8', level=logging.DEBUG, format='%(asctime)s %(levelname)s:%(message)s', filemode='w') bot = telebot.TeleBot(os.getenv('TG_BOT_TOKEN')) @bot.message_handler(content_types=['text']) def get_text_messages(message): bot.send_message(message.from_user.id, 'I`m working on your message!') logging.info(f'Working on message {message.text}') while True: # do something with message.text time.sleep(60) if __name__ == "__main__": while True: try: bot.polling(none_stop=True) except Exception as e: logging.error(e) bot.send_message(chat_id='DM with me', text='The bot just died! Please resend the messages!') time.sleep(5)
测试情况:向Bot发送三条消息MESSAGE1、MESSAGE2、MESSAGE3后,example.log仅记录前两条的请求及INFO日志,MESSAGE3无任何日志,说明第三个函数实例未启动。
问题原因
- 线程池资源耗尽:
telebot的polling方法默认线程池大小为2,你的消息处理函数是无限循环(while True),会长期占用线程,前两条消息直接占满所有可用线程,第三条消息没有线程可以分配。 - 阻塞式处理逻辑:消息处理函数执行后不会主动释放线程,线程被无限循环持续占用,导致线程池无法处理新的消息请求。
解决方案
1. 临时增大线程池数量
修改polling方法的num_threads参数,增加可用线程数,比如设置为5:
bot.polling(none_stop=True, num_threads=5)
注意:这只是临时缓解方案,若消息数量超过线程池大小,仍会出现同样问题,且大量长期运行的线程会持续占用系统资源。
2. 用独立线程处理耗时任务
将无限循环的耗时任务放到单独线程中执行,让消息处理函数快速完成并释放线程池资源:
import os, time import telebot import threading import logging logging.basicConfig(filename='example.log', encoding='utf-8', level=logging.DEBUG, format='%(asctime)s %(levelname)s:%(message)s', filemode='w') bot = telebot.TeleBot(os.getenv('TG_BOT_TOKEN')) def long_running_task(message_text, user_id): while True: # 执行定时HTTP请求、数据处理等操作 logging.info(f'Processing task for message: {message_text}') time.sleep(60) @bot.message_handler(content_types=['text']) def get_text_messages(message): bot.send_message(message.from_user.id, 'I`m working on your message!') logging.info(f'Working on message {message.text}') # 启动后台线程执行耗时任务 threading.Thread(target=long_running_task, args=(message.text, message.from_user.id), daemon=True).start() if __name__ == "__main__": while True: try: bot.polling(none_stop=True) except Exception as e: logging.error(e) bot.send_message(chat_id='DM with me', text='The bot just died! Please resend the messages!') time.sleep(5)
此方案中,消息处理函数执行后立即释放线程,线程池可继续处理新消息,耗时任务在后台独立线程运行。
3. 改用异步框架(推荐)
若Bot需处理大量长期运行的任务,建议使用原生支持异步的Telegram Bot库(如aiogram),它能更高效地处理并发请求,从根源避免线程资源耗尽的问题。
内容的提问来源于stack exchange,提问作者Rubisko
相关产品推荐
相关产品推荐

