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

Flask对接PostgreSQL出现psycopg2 Too many open files报错如何解决

问题根因

  1. 服务级文件描述符限制未生效:你修改的/etc/security/limits.conf仅对PAM登录的用户会话生效,若使用systemd管理gunicorn/nginx服务,或gunicorn启动时未单独配置文件限制,全局配置不会对服务进程生效。
  2. 原生SQL操作存在连接泄漏:你调用db.engine.execute()执行原生SQL后仅关闭了结果集,没有显式释放底层数据库连接,虽然配置了NullPool,但每个未释放的连接都会占用一个socket文件描述符,高并发下很快触达上限。
  3. 多线程下全局Session使用不规范:多线程场景下直接使用全局的db.session,线程本地的Session如果没有正确销毁,会残留额外的数据库连接。
  4. (可选)同时使用gunicorn和mod_wsgi会额外增加链路层的资源占用,两者都是WSGI容器,无需同时部署。

修复方案

1. 生效服务级文件描述符限制

  • 若使用systemd管理gunicorn服务,在service配置文件(通常路径为/etc/systemd/system/你的服务名.service)的[Service]段添加如下配置:
LimitNOFILE=500000
LimitNPROC=500000

修改后执行systemctl daemon-reload,再重启gunicorn服务。

  • gunicorn启动参数添加--limit-no-file 500000,确保worker进程继承配置。
  • 验证方式:执行ps aux | grep gunicorn找到worker进程ID,再执行cat /proc/<进程ID>/limits,确认Max open files数值为500000即配置生效。

2. 修复数据库操作逻辑

ORM插入逻辑优化

多线程场景下每次操作单独创建Session,不要复用全局db.session:

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=db.engine)

session = Session()
try:
    user_buy_sell = UserBuySell(app_name=self.app_name.lower(),username=self.user_id)
    session.add(user_buy_sell)
    session.commit()
finally:
    session.close()

原生SQL执行逻辑优化

用上下文管理器自动管理连接,避免手动释放遗漏:

with db.engine.connect() as conn:
    result = conn.execute(read_sql)
    for res in result:
        totalCount = int(res['totalcount'])
        break
# 退出上下文时会自动释放连接,无需手动关闭result/conn

原写法中db.engine.execute()是SQLAlchemy旧版本的隐式连接调用,仅关闭结果集不会释放底层连接,是泄漏的核心原因。

3. 可选优化

  • 移除mod_wsgi,仅保留gunicorn作为WSGI容器即可,减少不必要的资源占用。
  • 若不需要每次新建数据库连接,可将NullPool替换为固定大小的连接池,配置参考:
SQLALCHEMY_ENGINE_OPTIONS = {
    'pool_size': 20,
    'max_overflow': 10,
    'pool_recycle': 120,
    'pool_pre_ping': True
}

通过限制最大连接数,从根源避免无限制创建socket。

  • 可执行lsof -p <gunicorn进程ID>查看进程打开的所有文件句柄,确认是否存在其他文件/ socket泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 20:54:02