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

Flask+MariaDB后端Flutter应用多用户访问时Web服务响应缓慢问题排查求助

解决Flask+MariaDB并发请求下响应时间暴涨的问题

嘿,这个问题我之前帮朋友排查过类似的——你现在遇到的根本问题是每次请求都手动创建和销毁数据库连接,这在并发场景下会直接拖垮性能!咱们来拆解下原因,再给出具体的解决办法:

为什么并发时响应时间暴跌?

数据库创建连接是个开销很大的操作:要完成TCP握手、权限验证、资源分配等一系列步骤。单用户请求时,这个开销不明显,但当多个请求同时进来,数据库要同时处理大量连接创建请求,加上MariaDB默认的连接数限制,会导致请求排队等待可用连接,响应时间自然从毫秒级涨到十几秒。

最优解决方案:使用数据库连接池

连接池的核心思路是提前创建一批数据库连接并复用,避免每次请求都重复创建销毁。Flask生态里有两种常用的实现方式:

方式1:用SQLAlchemy自带连接池(推荐,整合更方便)

SQLAlchemy是Flask常用的ORM框架,自带成熟的连接池管理,不用自己手动维护。步骤如下:

  1. 先安装依赖:
pip install sqlalchemy pymysql
  1. 重构你的代码,让SQLAlchemy管理连接:
from flask import Flask, request, jsonify
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

app = Flask(__name__)

# 初始化数据库引擎,自带连接池,参数可根据并发量调整
# 格式:mysql+pymysql://用户名:密码@主机:端口/数据库名
engine = create_engine(
    'mysql+pymysql://your_user:your_password@localhost:3306/your_db',
    pool_size=10,       # 连接池常驻连接数
    max_overflow=20     # 峰值时允许的额外临时连接数
)
# 创建会话工厂,用于获取数据库连接
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# 定义获取数据库会话的工具函数
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.route('/ws_name', methods=['GET'])
def ws_name():
    # 从连接池获取一个连接会话
    db = next(get_db())
    try:
        param = request.args.get('param')
        # 执行查询(这里替换成你的实际SQL)
        query_result = db.execute(
            "SELECT * FROM your_table WHERE your_param = :param",
            {"param": param}
        ).fetchall()
        
        # 把查询结果转成JSON友好的格式
        result = [dict(row) for row in query_result]
    except Exception as e:
        # 这里可以加日志记录错误,方便排查
        return jsonify({"error": str(e)}), 500
    return jsonify(result), 200

方式2:用DBUtils独立连接池(适合不想用ORM的场景)

如果你不想引入ORM,DBUtils是专门做数据库连接池的工具库,用法也很简单:

  1. 安装依赖:
pip install DBUtils pymysql
  1. 重构代码:
from flask import Flask, request, jsonify
from DBUtils.PooledDB import PooledDB
import pymysql

app = Flask(__name__)

# 初始化连接池
db_pool = PooledDB(
    creator=pymysql,          # 指定连接驱动
    maxconnections=15,        # 连接池最大连接数
    mincached=2,              # 初始化时保持的空闲连接数
    host='localhost',
    user='your_user',
    password='your_password',
    database='your_db',
    port=3306
)

@app.route('/ws_name', methods=['GET'])
def ws_name():
    # 从连接池获取连接(注意:这里close是放回池,不是真销毁)
    cnx = db_pool.connection()
    cursor = None
    try:
        param = request.args.get('param')
        cursor = cnx.cursor()
        cursor.execute("SELECT * FROM your_table WHERE your_param = %s", (param,))
        
        # 把结果转成字典
        columns = [desc[0] for desc in cursor.description]
        result = [dict(zip(columns, row)) for row in cursor.fetchall()]
    except Exception as e:
        return jsonify({"error": str(e)}), 500
    finally:
        if cursor:
            cursor.close()
        cnx.close()  # 将连接放回连接池
    return jsonify(result), 200

额外优化建议

  1. 调整MariaDB连接数限制:登录MariaDB执行SHOW VARIABLES LIKE 'max_connections';,如果当前值太小(比如默认151),可以根据你的并发量调整,比如改成500(注意不要超过服务器内存承载能力)。
  2. 优化SQL查询:检查你的查询语句是否有索引缺失,比如function_execute_many_query里的查询,如果是全表扫描,并发时会大幅增加数据库负载。可以用EXPLAIN分析查询语句。
  3. 添加请求日志:记录每个请求的响应时间、数据库操作耗时,方便后续定位性能瓶颈。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 10:27:29