Anc*_*nia 0 python heroku celery flask flask-sqlalchemy
我正在尝试在heroku上部署Flask应用程序,该应用程序在Celery中使用后台任务。我已经实现了应用程序工厂模式,以便将celery进程不绑定到flask应用程序的任何一个实例。
这在本地有效,但我还没有看到错误。但是,当部署到heroku时,总是会出现相同的结果:celery任务(我只使用一个)在第一次运行时成功,但是对该任务的所有后续celery调用均失败sqlalchemy.exc.DatabaseError: (psycopg2.DatabaseError) SSL error: decryption failed or bad record mac。如果我重新启动芹菜工人,循环将继续。
有多个 问题表明此错误,但没有一个问题指定正确的解决方案。最初,我认为实现应用程序工厂模式将阻止此错误的出现,但还不完全如此。
在app/__init__.py我创建celery和db对象中:
celery = Celery(__name__, broker=Config.CELERY_BROKER_URL)
db = SQLAlchemy()
def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
db.init_app(app)
return app
Run Code Online (Sandbox Code Playgroud)
我的flask_celery.py文件创建了实际的Flask应用程序对象:
import os
from app import celery, create_app
app = create_app(os.getenv('FLASK_CONFIG', 'default'))
app.app_context().push()
Run Code Online (Sandbox Code Playgroud)
我用以下命令开始芹菜:
celery worker -A app.flask_celery.celery --loglevel=info
实际的芹菜任务如下所示:
@celery.task()
def task_process_stuff(stuff_id):
stuff = Stuff.query.get(stuff_id)
stuff.processed = True
db.session.add(stuff)
db.session.commit()
return stuff
Run Code Online (Sandbox Code Playgroud)
通过以下方式调用:
task_process_stuff.apply_async(args=[stuff.id], countdown=10)
Run Code Online (Sandbox Code Playgroud)
图书馆版本
解决方案是db.engine.dispose()在任务开始时添加,在开始任何工作之前处理所有数据库连接:
@celery.task()
def task_process_stuff(stuff_id):
db.engine.dispose()
stuff = Stuff.query.get(stuff_id)
stuff.processed = True
db.session.commit()
return stuff
Run Code Online (Sandbox Code Playgroud)
由于我在所有任务中都需要此功能,因此将其添加到task_prerun:
@task_prerun.connect
def on_task_init(*args, **kwargs):
db.engine.dispose()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
676 次 |
| 最近记录: |