我使用Flask构建了一个小型的Python REST服务,Flask-SQLAlchemy用于与MySQL DB进行通信。
如果我直接连接到MySQL服务器,一切都很好,没有任何问题。如果我使用HAproxy(处理HA /故障转移,虽然在这个开发环境中只有一个数据库服务器),如果应用程序没有经常与数据库通信,我会不断出现MySQL server has gone away
错误。
我的HAproxy客户端超时设置为50秒,所以我认为它会切断流,但应用程序不知道并尝试使用无效连接。
在使用HAproxy等服务时,我应该使用哪种设置?
此外它似乎没有自动重新连接,但如果我手动发出请求,我会收到Can't reconnect until invalid transaction is rolled back
,这很奇怪,因为它只是我正在进行的select()
通话,所以我不喜欢我认为它是commit()
我错过了 - 或者我应该在每个基于ORM的查询后调用commit()吗?
答案 0 :(得分:4)
只是用一个答案整理这个问题,我会发布我(我想)解决问题的方法。
问题1:HAproxy
SQLALCHEMY_POOL_RECYCLE = 30
(在我的情况下为30小于HAproxy客户端超时),以便在初始化数据库时,它将引入这些设置并在HAproxy自行删除之前回收连接。与this issue on SO类似。 问题2:Can't reconnect until invalid transaction is rolled back
我相信我通过调整数据库初始化和跨各种模块导入的方式来解决这个问题。我现在基本上只有一个模块:
from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
然后在我的主application factory中,我只是:
from common.database import db
db.init_app(app)
此外,由于我想自动轻松加载表结构,我在应用程序上下文中初始化了元数据绑定,我认为这是干净地处理我遇到的commit()
问题/错误,因为我相信数据库现在,每次请求后都会正确终止会话。
with app.app_context():
# Setup DB binding
db.metadata.bind = db.engine