转载 

sqlalchemy.exc.TimeoutError: QueuePool limit of size 10 overflow 10 reached ...

分类:python,Mysql    1322人阅读    IT小君  2022-11-20 21:37

解决方法1:在代码中添加以下方法。

 @app.teardown_appcontext

    def shutdown_session(exception=None):

        db.session.remove()

它将自动关闭所有未使用的/挂起的连接,并防止代码中的瓶颈。特别是当您使用以下语法:Model.query.filter,通过(attribute=var).first()和关系/延迟加载来过滤。

 

问题产生

flask程序使用sqlalchemy或flask-sqlalchemy运行一段时间后,会报该错误

 

sqlalchemy.exc.TimeoutError: QueuePool limit of size 10 overflow 10 reached, connection timed out, timeout 30 (Background on this error at: http://sqlalche.me/e/3o7r)

 

问题产生原因分析

产生该问题的原因有种,并发太高等都可能引起该错误,

 

还有一个典型的错误原因是,在客户端发送一个请求后, flask后台执行一个数据库操作,随后进行某种逻辑操作,如果该逻辑出现错误,会为客户端返回500错误码,此时该连接未释放,因此会导致数据库连接池继续占用。如下代码

 

@web.route("/test_error")

def test_error():

    print("-----------------error times "+ str(datatemp.error_counter)+"------------")

    datatemp.error_counter += 1

    sites = Site.query.filter().all()

    r = requests.get('http://github.com', timeout=0.001)

    return "error times "+ str(datatemp.error_counter)

requsts.get会必定报错,该逻辑之前 执行了查询操作,因此不会释放连接。

 

向/test_error连续发送20个请求,就会出现连接池错误。

 

解决方案2  增加连接池

操作如链接所示:增加连接池

 

该解决方案仅仅适合由于用户高并发引起的该问题,对于本文所述情况,该解决方案仅仅能延缓该问题,无法解决该问题。

 

解决方案3 增加try_except

在可能出错的语句,增加try字段

 

如上述代码可以修改为

 

@web.route("/test_error")

def test_error():

    print("-----------------error times "+ str(datatemp.error_counter)+"------------")

    datatemp.error_counter += 1

    sites = Site.query.filter().all()

    try:

        r = requests.get('http://github.com', timeout=0.001)

    except:

        r = None

    return "error times "+ str(datatemp.error_counter)

可以解决本文所述情况引起的连接池错误,但是时间成本过长,尤其项目规模较大时

 

解决方案4 使用redis

这个解决思路来源于Stack Overflow,本人尚未验证,

理论上来说即为可行,可以解决高并发,本问所述问题等

支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者

 工具推荐 更多»