我有一个Flask应用程序来启动长时间运行的Celery任务(大约10-120分钟/任务,有时查询很慢)。我使用Flask-SQLAlchemy进行ORM和连接管理。我的应用程序如下所示:
app = Flask(__name__)
db = SQLAlchemy(app)
celery = make_celery(app)
@app.route('/start_job')
def start_job():
task = job.delay()
return 'Async job started', 202
@celery.task(bind=True)
def job(self):
db.session.query(... something ...)
... do something for hours ...
db.session.add(... something ...)
db.session.commit()
return不幸的是,我不得不使用的MySQL服务器喜欢在几分钟不活动后关闭连接,而celery任务不能处理这种情况,所以在等待了很长时间后,我得到了(2006,'MySQL服务器已经消失了‘)错误。AFAIK连接池应该处理关闭的连接。我读了docs,但它只写了SQLALCHEMY_POOL_TIMEOUT和SQLALCHEMY_POOL_RECYCLE参数,所以基于一些随机的互联网文章,我试图将回收改为3分钟,但这没有帮助。
如何连接(会话?)这种配置下的处理工作吗?我应该怎么做才能避免这样的错误?
发布于 2017-02-22 02:21:53
我不能完全确定下面的解决方案的好处,但它似乎解决了问题。
会话在第一个查询(或插入)语句之前初始化连接并启动事务。然后,它等待回滚或提交,但由于不活动,MySQL服务器在几分钟后关闭连接。解决方案是,如果您长时间不需要该会话,则关闭该会话,然后SQLAlchemy将为下一个事务打开一个新会话。
@celery.task(bind=True)
def job(self):
db.session.query(... something ...)
db.session.close()
... do something for hours ...
db.session.add(... something ...)
db.session.commit()
returnhttps://stackoverflow.com/questions/42310062
复制相似问题