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

如何解决同时运行Discord.py客户端与Uvicorn应用的阻塞问题

问题根因
  • 配置错误:uvicorn设置workers=3仅在主进程启动模式生效,在线程中运行时该配置失效,还会干扰事件循环绑定
  • 事件循环冲突:discord.py的client.run()是阻塞调用,会独占当前线程的事件循环,你启动的uvicorn子线程未手动初始化独立事件循环,异步逻辑无法正常执行
  • 语法错误:你定义的on_ready回调多带了self参数,事件触发时会抛出异常,影响服务运行
推荐解决方案(同事件循环部署,轻量适配)

直接将两个异步服务挂载到同一个事件循环中运行,无需多线程处理,代码修改如下:

# main.py 修正版
import asyncio
from discord.ext.commands import Bot
import uvicorn
# 导入api.py中的FastAPI实例
from api import app
# discord.py v2.x需要显式配置intents
import discord
intents = discord.Intents.default()
# 按需开启需要的权限,比如接收消息内容需要开启message_content
intents.message_content = True

client = Bot(command_prefix="!", intents=intents)

@client.event
async def on_ready():
    print(f"Bot online, logged in as {client.user}")

# 启动FastAPI服务的协程
async def run_api():
    config = uvicorn.Config(
        app,
        host="127.0.0.1",
        port=8000,
        log_level="info"
    )
    server = uvicorn.Server(config)
    await server.serve()

async def main():
    # 先启动API服务作为后台任务
    asyncio.create_task(run_api())
    # 再启动Discord机器人
    await client.start("你的机器人TOKEN")

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

注意事项

  • 不要给uvicorn配置loop和workers参数,直接使用当前事件循环即可,多worker模式无法和Discord bot共享事件循环
  • 替换代码中的TOKEN为你实际的机器人令牌,按需调整Bot的命令前缀和intents权限
生产环境最优方案(多进程分离部署)

如果需要更高的稳定性和API扩容能力,直接将两个服务拆分为独立进程运行,完全避免耦合:

  1. 单独运行Discord机器人:python main.py(main.py仅保留机器人相关逻辑,去掉API相关代码)
  2. 单独运行FastAPI服务:uvicorn api:app --host 127.0.0.1 --port 8000 --workers 3
  3. 两个服务之间如果需要通信,通过HTTP接口调用或者Redis中间件实现即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:21:02