无法直连MySQL时,如何通过SqlAlchemy获取FastAPI应用的DB指标?
从SQLAlchemy获取数据库连接/性能指标排查FastAPI连接冻结问题
一、连接池核心指标(从Engine对象获取)
连接池状态是排查连接冻结的核心依据,这些指标能直接反映池内连接的使用负载:
- 已被占用的连接数:
engine.pool.checkedout() - 空闲待使用的连接数:
engine.pool.checkedin() - 连接池配置的最大容量:
engine.pool.size() - 超出池容量的临时连接数:
engine.pool.overflow()
二、会话与连接关联指标(从Session对象获取)
每个Session对应一个底层数据库连接,这些指标能追踪会话的实时状态:
- 会话是否绑定了活跃连接:
db.is_active - 底层连接的唯一标识(用于区分不同连接实例):
id(db.connection()) - 连接存活时长(需配合事件监听实现):记录连接创建时间,计算当前时长
三、整合指标的日志示例(替换你的logger.info)
把这些指标嵌入到你的get_db函数中,修改后的代码如下:
from sqlalchemy import event from datetime import datetime # 存储连接创建时间的字典,用于计算连接存活时长 connection_create_times = {} # 监听连接创建事件,记录每个连接的生成时间 @event.listens_for(engine, "connect") def record_connect_time(dbapi_connection, connection_record): connection_create_times[id(dbapi_connection)] = datetime.now() def get_db() -> Session: db = SessionLocal() # 提取连接池指标 pool_checkedout = engine.pool.checkedout() pool_checkedin = engine.pool.checkedin() pool_size = engine.pool.size() pool_overflow = engine.pool.overflow() # 提取会话与连接的关联指标 session_active = db.is_active conn_id = id(db.connection()) if session_active else "N/A" conn_age = (datetime.now() - connection_create_times.get(conn_id, datetime.now())).total_seconds() if session_active else 0 # 输出整合后的指标日志 logger.info( f"DB Session Metrics - " f"Pool: 已占用={pool_checkedout}, 空闲={pool_checkedin}, 容量={pool_size}, 溢出={pool_overflow} | " f"Session: 活跃={session_active}, 连接ID={conn_id}, 连接存活时长={conn_age:.2f}s" ) try: yield db except Exception as exc: db.rollback() logger.error(f'DBRROR: {traceback.format_exc()}') raise exc finally: # 可选:会话关闭时记录连接归还日志 logger.debug(f"会话关闭,连接{conn_id}归还至连接池") db.close() # 清理已关闭连接的时间记录 if conn_id in connection_create_times: del connection_create_times[conn_id]
四、排查方向提示
- 如果
pool_checkedout长期等于pool_size+pool_overflow,说明连接池被完全占满,大概率是会话未被正确关闭(检查所有使用db的代码路径是否走到了finally块) - 若
conn_age超过你设置的pool_recycle值(你当前设了57400秒,但MySQL默认wait_timeout是28800秒),说明连接可能已失效却未被回收,需要调整pool_recycle到小于MySQL的超时时间 - 临时开启
engine = create_engine(..., echo=True),可以看到所有SQL执行和连接的建立/关闭日志,快速定位慢查询或异常连接操作
内容的提问来源于stack exchange,提问作者Vyacheslav
相关产品推荐
相关产品推荐

