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

Pycord开发的Discord Bot频繁离线停止响应问题排查

Pycord Bot自定义启动后频繁离线的排查方案

问题本质

你的情况核心是自定义启动逻辑缺失了bot.run()内置的连接维持、心跳管理和自动重连机制。用bot.run()时正常,说明Bot本身的业务逻辑没问题,问题出在main()协程对事件循环、连接生命周期的处理上。每10分钟触发on_ready()但on_connect()不触发,是因为Discord网关判定连接超时后被动触发重连,而非Bot主动发起的新连接。

重点排查方向

1. 事件循环管理错误

自定义启动时如果手动处理事件循环却没让它持续运行,或者某个任务结束后意外终止了循环,会导致Pycord无法维持心跳,Discord网关断开连接后只能被动等待重连。

  • 检查main()里是否用asyncio.run()正确托管整个流程,不要手动调用loop.stop()之类的方法提前终止循环。
  • 确保所有异步任务(包括Bot启动、数据库操作)都绑定到同一个事件循环,不要混用多个循环实例。

2. asyncpg与事件循环的冲突

你最初遇到的"Task is already in progress"错误,本质是asyncpg的连接池和Pycord的事件循环没有共享资源。自定义启动时如果先初始化asyncpg再启动Bot,或者反过来,要确保两者使用同一个循环:

async def main():
    # 先初始化数据库连接池,绑定到当前循环
    bot.db_pool = await asyncpg.create_pool(user="user", password="pass", database="db")
    try:
        # 启动Bot,自动复用当前事件循环
        await bot.start("YOUR_BOT_TOKEN")
    finally:
        # 确保Bot退出时关闭数据库连接池
        await bot.db_pool.close()

if __name__ == "__main__":
    asyncio.run(main())

3. 缺失重连异常处理

bot.run()内部会自动捕获连接断开、心跳超时等异常并发起重连,自定义启动时如果只调用await bot.start(),遇到网络波动或网关断开时Bot会直接停止,只能等待Discord的被动重连(间隔约10分钟)。要手动添加异常捕获和重连逻辑:

async def main():
    bot.db_pool = await asyncpg.create_pool(...)
    try:
        await bot.start("YOUR_BOT_TOKEN")
    except (discord.ConnectionClosed, asyncio.TimeoutError, asyncio.CancelledError) as e:
        print(f"连接异常,尝试重连: {str(e)}")
        # 可以添加重连次数限制,避免无限递归
        await main()
    finally:
        await bot.db_pool.close()

4. 事件循环被阻塞

如果有耗时的数据库查询或同步操作阻塞了事件循环,Pycord无法按时发送心跳,会被Discord网关判定为超时断开。

  • 检查所有任务,替换time.sleep()为asyncio.sleep(),避免同步阻塞。
  • 耗时的数据库操作或同步代码,放到线程池中执行:
from concurrent.futures import ThreadPoolExecutor

async def heavy_db_operation():
    def sync_task():
        # 耗时的同步数据库操作
        return bot.db_pool.fetch("SELECT * FROM large_table")
    loop = asyncio.get_running_loop()
    result = await loop.run_in_executor(ThreadPoolExecutor(), sync_task)
    return result

调试技巧

开启Pycord的调试日志,能直接看到网关连接、心跳、断开的详细信息,快速定位问题:

import logging
logging.basicConfig(level=logging.DEBUG)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 16:23:15