默认create_engine虽用queuepool但pool_size=5、max_overflow=10,高并发下易达连接上限致超时或“too many connections”;须按qps调参并设pool_recycle

因为不配连接池,create_engine 默认只做连接复用的“表面功夫”,实际高并发下仍会频繁新建连接,直接触发 MySQL 的 Too many connections 错误,应用响应变慢甚至雪崩。
不配置连接池时 create_engine 的真实行为
很多人以为只要用了 create_engine 就自动有连接池——其实不是。默认情况下它用的是 QueuePool,但 pool_size=5、max_overflow=10,意味着最多只允许 15 个连接;一旦并发请求超过这个数,后续请求就会阻塞在 pool_timeout=30(默认值)上,超时后抛出 TimeoutError。
- 现象:接口偶发 504 或长时间卡顿,日志里出现
QueuePool limit of size 5 overflow 10 reached - 根本原因:没根据业务 QPS 调整
pool_size和max_overflow,也没设pool_recycle防 MySQL 的wait_timeout(默认 8 小时,但云数据库常设为 300 秒) - 误区:把
echo=True当成“已启用连接池”的标志——它只打印 SQL,和连接管理无关
pool_recycle 不设会导致连接静默失效
MySQL 服务端会主动断开空闲超过 wait_timeout 的连接。如果 SQLAlchemy 连接池里的连接没被检测或回收,下次取出时就可能报 Lost connection to MySQL server during query。
- 必须设
pool_recycle,且值要小于数据库的wait_timeout(例如 MySQL 云实例常为 300 秒,则设pool_recycle=280) -
pool_pre_ping=True可以在每次取连接前执行SELECT 1检测,但会增加一次往返延迟,生产环境建议和pool_recycle配合使用,而非单独依赖它 - SQLite 等本地数据库不用设
pool_recycle,但也要注意线程安全(默认poolclass是线程安全的QueuePool)
异步场景下必须用 create_async_engine,不能复用同步配置
用 async def 却配了普通 create_engine,会导致协程被阻塞在连接获取上,失去异步意义。
- 异步驱动必须匹配:MySQL 用
mysql+aiomysql或mysql+asyncmy,PostgreSQL 用postgresql+asyncpg - 参数名一致,但底层池实现不同:
create_async_engine返回的是AsyncEngine,必须配合async with engine.connect()使用 - 别混用:同步代码里调
await conn.execute(...)会报RuntimeWarning: coroutine 'XXX' was never awaited
真正容易被忽略的点是:连接池参数不是“设一次就完事”。它得跟着部署环境走——开发机跑 5 个请求没问题,上线后每秒 200 QPS,pool_size=5 就成了瓶颈。得结合监控看 engine.pool.checkedin(), engine.pool.checkedout() 实时水位,而不是只靠经验拍脑袋。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











