Flask-SQLAlchemy 和 Gevent 没有关闭 mysql 连接

Posted

技术标签:

【中文标题】Flask-SQLAlchemy 和 Gevent 没有关闭 mysql 连接【英文标题】:Flask-SQLAlchemy and Gevent not closing mysql connections 【发布时间】:2015-09-11 20:50:59 【问题描述】:

我目前正在使用Flask-uWSGI-Websockets 为我的应用程序提供 websocket 功能。我使用 Flask-SQLAlchemy 连接到我的 mysql 数据库。

Flask-uWSGI-Websockets 使用 gevent 来管理 websocket 连接。

我目前遇到的问题是,当一个 websocket 连接结束时,Flask-SQLAlchemy 建立的数据库连接将继续存在。

我尝试在每次 websocket 连接后调用 db.session.close()db.engine.dispose(),但这没有效果。

在我的应用开始时调用 gevent.monkey.patch_all() 并没有什么不同。

我正在做的一个简单的表示是这样的:

from gevent.monkey import patch_all
patch_all()

from flask import Flask
from flask_uwsgi_websocket import GeventWebSocket
from flask_sqlalchemy import SQLAlchemy

app = Flask()
ws = GeventWebSocket()
db = SQLAlchemy()

db.init_app(app)
ws.init_app(app)


@ws.route('/ws')
def websocket(client):
    """ handle messages """
    while client.connected is True:
        msg = client.recv()
        # do some db stuff with the message

    # The following part is executed when the connection is broken,
    # i tried this for removing the connection, but the actual
    # connection will stay open (i can see this on the mysql server).
    db.session.close()
    db.engine.dispose()

【问题讨论】:

您确定已达到会话结束代码吗?是否会引发异常?在这种情况下,我会将会话结束代码放在 finally 语句的正文中 【参考方案1】:

我也有同样的情况。和我的解决方案位于mysql配置文件my.cnf

[mysqld]
interactive_timeout=180
wait_timeout=180

保存my.cnf后必须重启mysql服务。

如果不想重启mysql服务,可以使用sql查询:

SET GLOBAL interactive_timeout = 180;
SET GLOBAL wait_timeout = 180;

另请参阅 mysql.com 上的 wait_timeout 和 interactive_timeout

【讨论】:

以上是关于Flask-SQLAlchemy 和 Gevent 没有关闭 mysql 连接的主要内容,如果未能解决你的问题,请参考以下文章

Flask-SQLAlchemy:用户角色模型和关系

WebSocket 传输不可用。安装 eventlet 或 gevent 和 gevent-websocket 以提高性能

Flask-Sqlalchemy 和水平缩放和范围会话

gevent猴子补丁和断点

gevent和tornado异步

FLASK-SQLALCHEMY如何使用or和and条件进行组合查询