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

FastAPI+Uvicorn应用中SQLAlchemy QueuePool溢出问题排查

问题分析与解决方案

核心原因

你遇到的连接池耗尽问题,核心是对单线程Uvicorn的工作模式理解有误:

  • 若你的API端点是用def定义的同步函数,Uvicorn会自动启动一个默认40个线程的线程池来并行处理这些请求,每个线程会独立创建数据库会话,直接超过你设置的pool_size=10 + max_overflow=20的总连接数上限。
  • 即使是异步端点,若使用同步SQLAlchemy会话,异步事件循环会为阻塞的DB操作额外启动线程,同样会产生多个并发连接,耗尽连接池。

解决方案

方案1:改用异步SQLAlchemy(推荐)

适配FastAPI的异步特性,使用SQLAlchemy异步引擎和会话,从根源避免线程池带来的并发问题:

# 异步数据库配置
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker

engine = create_async_engine(
    settings.DATABASE_URI,
    pool_pre_ping=True,
    pool_size=10,
    max_overflow=20
)
AsyncSessionLocal = sessionmaker(
    autocommit=False,
    autoflush=False,
    bind=engine,
    class_=AsyncSession
)

# 异步依赖函数
async def get_db():
    async with AsyncSessionLocal() as session:
        yield session

对应的异步端点写法:

from sqlalchemy import select
from your_models import Item

@app.get("/items/{item_id}")
async def read_item(item_id: int, db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(Item).where(Item.id == item_id))
    item = result.scalar_one_or_none()
    return item

方案2:限制Uvicorn同步线程池大小

若暂时无法重构为异步,调整Uvicorn的并发限制,让线程池大小不超过数据库连接池总容量(30):

命令行启动时配置

uvicorn main:app --workers 1 --limit-concurrency 30

代码内配置

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=8000,
        workers=1,
        limit_concurrency=30
    )

同时要优化同步端点的数据库操作,减少连接持有时间(比如避免慢查询)。

方案3:调整数据库连接池参数

若业务确实需要更高并发,可适当调大连接池参数,但要注意不超过MySQL的max_connections配置(默认151):

engine = create_engine(
    settings.DATABASE_URI,
    pool_pre_ping=True,
    pool_size=20,  # 增大基础连接数
    max_overflow=30,  # 增大溢出连接数
    pool_recycle=3600  # 自动回收闲置1小时的连接,避免长期占用
)

额外排查点

  • 验证连接是否正确释放:在get_db的finally块添加日志,确认每个会话都被关闭:
def get_db():
    db = SessionLocal() 
    try:
        yield db
    finally:
        print(f"Closing session {db}")
        db.close()
  • 检查慢查询:长时间运行的SQL会让连接长期占用,导致连接池耗尽,可通过MySQL的慢查询日志定位并优化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 22:52:38