You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用aiogram开发Telegram Bot时长期运行触发asyncio.TimeoutError问题求助

排查aiogram Bot长时间运行后出现的TimeoutError问题

从你的错误栈来看,这个超时错误发生在get_updates请求阶段——也就是Bot和Telegram服务器建立连接获取更新时失败了。结合你提到的「长时间运行后出现」的情况,我来帮你拆解可能的成因和对应的解决办法:

一、最可能的成因:电脑休眠/睡眠模式

你怀疑的电脑休眠确实是高频触发原因:当电脑进入休眠状态时,网络连接会被切断,Bot无法和Telegram服务器通信,自然会触发请求超时。

解决办法:

  • 关闭自动休眠:根据你的操作系统调整电源设置,比如Mac在「系统设置-电池」里关闭自动睡眠,Windows在「电源选项」中设置「从不休眠」。
  • 部署到云服务器:如果需要Bot长期稳定运行,本地电脑始终有休眠、关机的风险,把Bot部署到VPS、云主机(比如阿里云、AWS轻量应用服务器)上是更彻底的方案,服务器可以24小时不间断运行。

二、网络不稳定导致的临时连接中断

即使电脑没休眠,长时间运行过程中网络波动、短暂断网也会引发这类超时。aiogram默认的轮询参数可能没有足够的重试机制来应对这类情况。

解决办法:

  1. 调整轮询参数
    修改start_polling的调用,增加超时、重试相关配置,让Bot遇到临时网络问题时自动重试:

    if __name__ == '__main__':
        executor.start_polling(
            dp,
            on_startup=on_startup,
            timeout=30,  # 延长单次请求超时时间
            retries=5,   # 设置请求失败后的重试次数
            skip_updates=True,  # 跳过Bot离线期间堆积的更新,避免启动后处理大量旧消息
            allowed_updates=types.AllowedUpdates.all()
        )
    
  2. 添加全局错误处理器
    在Dispatcher中注册错误处理器,专门捕捉TimeoutError并做日志记录或自动恢复:

    @dp.errors_handler()
    async def handle_timeout_error(update: types.Update, exception: Exception):
        if isinstance(exception, asyncio.TimeoutError):
            logging.warning("检测到请求超时,将自动重试连接")
            return True  # 返回True表示已处理该错误,避免程序崩溃
        # 其他错误的处理逻辑
        logging.exception(f"未处理的异常: {exception}")
        return True
    

三、aiogram版本或Session配置问题

旧版本的aiogram可能存在轮询逻辑的bug,或者默认的aiohttp Session配置不够稳定。

解决办法:

  • 升级aiogram:用pip安装最新版本,修复已知的稳定性问题:
    pip install --upgrade aiogram
    
  • 自定义aiohttp Session:如果默认Session不够稳定,可以创建带超时和连接池配置的自定义Session:
    from aiohttp import ClientTimeout, TCPConnector
    
    # 创建自定义Session配置
    timeout = ClientTimeout(total=60)
    connector = TCPConnector(limit=10, keepalive_timeout=30)
    
    bot = Bot(
        token=config.BOT_TOKEN,
        parse_mode=types.ParseMode.HTML,
        timeout=timeout,
        connector=connector
    )
    

四、改用Webhook替代长轮询(长期优化方案)

长轮询本质是Bot主动向Telegram服务器请求更新,长时间运行下确实容易遇到连接问题。而Webhook是Telegram服务器主动将更新推送到你的Bot服务端,稳定性更高,适合长期运行的Bot。

简单示例(需要公网可访问的地址):

if __name__ == '__main__':
    # 假设你的公网地址是https://your-domain.com/webhook
    executor.start_webhook(
        dispatcher=dp,
        webhook_path='/webhook',
        skip_updates=True,
        on_startup=on_startup,
        host='0.0.0.0',
        port=8080,
        url='https://your-domain.com/webhook'
    )

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

火山引擎 最新活动