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

Flask默认开发服务器连接PostgreSQL出现too many open files错误求助

解决"too many open files"错误的方案

核心问题分析

  • 未实际利用pgbouncer连接池:你的get_db_connection函数直接连接PostgreSQL数据库,而非pgbouncer的监听地址,等于绕过了连接池管理,每个请求都会新建数据库连接,高并发场景下很快耗尽系统文件句柄(每个数据库连接对应一个socket文件)。
  • 异常处理存在连接泄漏风险:except块中使用cur.execute('rollback')是错误操作,正确的回滚方式是调用conn.rollback();若此处抛出异常,后续的游标和连接关闭逻辑可能无法执行,导致连接资源泄漏。
  • Flask默认服务器不适合高并发:Flask自带的开发服务器为多线程模式,但性能有限,面对IoT设备高频推送的请求时,易引发资源耗尽问题。

具体修复步骤

1. 修改数据库连接,接入pgbouncer

将get_db_connection中的连接目标改为pgbouncer的地址和端口,而非直接连接PostgreSQL:

def get_db_connection():
    conn = psycopg2.connect(
        dbname="database",
        port="6432",  # 替换为pgbouncer实际监听端口,默认6432
        host="pgbouncer_host",  # 替换为pgbouncer所在的IP或主机名
        user="username",
        password="password",
        cursor_factory=psycopg2.extras.RealDictCursor
    )
    return conn

2. 修复异常处理与资源释放逻辑

使用finally块确保无论请求是否成功,游标和连接都能被正确关闭,同时修正回滚操作并优化SQL执行方式:

@app.route('/aqi/add', methods=['POST'])
def addAQI():
    conn = None
    cur = None
    response = None
    try:
        conn = get_db_connection()
        cur = conn.cursor()

        if request.method == 'POST':
            data = request.form
            # 数据获取逻辑保持不变
            co_ugm3 = data.get('co', default=0)
            no2_ugm3 = data.get('no2', default=0)
            so2_ugm3 = data.get('so2', default=0)
            o3_ugm3 = data.get('o3', default=0)
            co2_ugm3 = data.get('co2', default=0)
            tvoc = data.get('tvoc', default=0)
            pm1_ugm3 = data.get('pm1', default=0)
            pm25_ugm3 = data.get('pm25', default=0)
            pm4_ugm3 = data.get('pm4', default=0)
            pm10_ugm3 = data.get('pm10', default=0)
            noise_dba = data.get('noise', default=0)
            datetime = data.get('datetime')
            h2s_ugm3 = data.get('h2s', default=0)
            station_name = data.get('station')
            battery_voltage_dc = data.get('battery', default=0)
            temperature_celsius = data.get('tmp', default=0)
            relative_humidity_percent = data.get('hr', default=0)
            barometric_pressure_hpa = data.get('hpa', default=0)
            station_id = data.get('station_id')

            # 使用参数化查询避免SQL注入,同时提升执行效率
            cur.execute("""
                INSERT INTO nifx_devices_data(
                    co_ugm3, no2_ugm3, so2_ugm3, o3_ugm3, co2_ugm3, tvoc, 
                    pm1_ugm3, pm25_ugm3, pm4_ugm3, pm10_ugm3, noise_dba, 
                    datetime, h2s_ugm3, station_name, battery_voltage_dc, 
                    temperature_celsius, relative_humidity_percent, 
                    barometric_pressure_hpa, station_id
                ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
            """, (
                co_ugm3, no2_ugm3, so2_ugm3, o3_ugm3, co2_ugm3, tvoc,
                pm1_ugm3, pm25_ugm3, pm4_ugm3, pm10_ugm3, noise_dba,
                datetime, h2s_ugm3, station_name, battery_voltage_dc,
                temperature_celsius, relative_humidity_percent,
                barometric_pressure_hpa, station_id
            ))
            conn.commit()
            response = Response(response=json.dumps({'Status': 1}), mimetype='application/json')
            response.status_code = 200
    except Exception as e:
        if conn:
            conn.rollback()
        print(e)
        response = Response(response=json.dumps({'Status': 0}), mimetype='application/json')
        response.status_code = 400
    finally:
        # 强制关闭游标和连接,避免资源泄漏
        if cur:
            cur.close()
        if conn:
            conn.close()
    return response

3. 调高系统文件句柄限制

若服务运行在Linux系统,可临时调高当前进程的文件句柄限制:

ulimit -n 65535

要永久生效,编辑/etc/security/limits.conf文件并添加:

* soft nofile 65535
* hard nofile 65535

同时调整pgbouncer配置文件(pgbouncer.ini)中的连接池参数:

max_client_conn = 1000  # 允许的最大客户端连接数
default_pool_size = 20   # 每个数据库的默认连接池大小

4. 替换Flask默认服务器

Flask默认开发服务器不适合生产高并发场景,改用Gunicorn或uWSGI:

# 安装Gunicorn
pip install gunicorn
# 启动服务,根据服务器配置调整进程和线程数
gunicorn --workers 4 --threads 2 app:app

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 08:15:52