带有mongodb结果后端的示例celery v4.2后端

时间:2018-10-27 00:43:15

标签: python-3.x mongodb celery

我正在尝试在Flask下设置一个Celery应用程序以接受API请求,然后分离Celery工作程序以执行长时间运行的任务。我的问题是我的Flask和环境中的其他所有东西都使用MongoDB,所以我不想仅为Celery结果设置单独的SQL数据库。我找不到如何使用MongoDB集群作为后端正确配置Celery的任何好例子。

以下是我尝试使其接受的设置:

CELERY_RESULT_BACKEND = "mongodb"
CELERY_MONGODB_BACKEND_SETTINGS = {"host": "mongodb://mongodev:27017",
                               "database": "celery",
                               "taskmeta_collection": "celery_taskmeta"}

无论我做什么,Celery似乎都会忽略配置设置,并且在没有任何结果后端的情况下启动。是否有使用最新版本的Celery的有效示例?我能找到的唯一其他示例是v3 Celery设置,这对我也不起作用,因为我在生产中使用了Mongo复制群集,该版本似乎不支持该群集。

[编辑]以复杂的方式添加更多信息,我将配置设置为与应用程序的其余部分一起使用。

首先将配置值作为环境变量通过docker-compose文件传递,如下所示:

environment:
  - PYTHONPATH=/usr/src/
  - APP_SETTINGS=config.DevelopmentConfig
  - FLASK_ENV=development
  - CELERY_BROKER_URL=amqp://guest:guest@rabbit1:5672
  - CELERY_BROKER_DEV=amqp://guest:guest@rabbit1:5672
  - CELERY_RESULT_SERIALIZER=json
  - CELERY_RESULT_BACKEND=mongodb
  - CELERY_MONGODB_BACKEND_SETTINGS={"host":"mongodb://mongodev:27017","database":"celery","taskmeta_collection":"celery_taskmeta"}

然后,在config.py文件中加载它们:

class DevelopmentConfig(BaseConfig):
    """Development configuration"""
    CELERY_BROKER_URL = os.getenv('CELERY_BROKER_DEV')
    CELERY_RESULT_SERIALIZER = os.getenv('CELERY_RESULT_SERIALIZER')
    CELERY_RESULT_BACKEND = os.getenv('CELERY_RESULT_BACKEND')
    CELERY_MONGODB_BACKEND_SETTINGS = ast.literal_eval(os.getenv('CELERY_MONGODB_BACKEND_SETTINGS'))

然后,在启动Celery时,将加载配置:

app = Celery('celeryworker', broker=os.getenv('CELERY_BROKER_URL'),
             include=['celeryworker.tasks'])
print('app initiated')
app.config_from_object(app_settings)
app.conf.update(accept_content=['json'])
print("CELERY_MONGODB_BACKEND_SETTINGS",
       os.getenv('CELERY_MONGODB_BACKEND_SETTINGS'))
print("celery config",app.conf)

当应用程序启动时,这是我所有故障排除打印的结果。我已经编辑了很多配置输出,只是为了表明我在这里通过config.py传递到app.config,但是被Celery忽略了。您可以看到该值将其添加到celery.py文件中,并且我确定Celery会对它进行某些操作,因为在将ast.literal_eval添加到config.py中之前,Celery会引发错误,指出MongoDB后端设置必须为dict,而不是字符串。不幸的是,由于恰如其分的命令Celery忽略了它,所以现在通过了它。

app_settings SGSDevOps.config.DevelopmentConfig
app initiated
CELERY_MONGODB_BACKEND_SETTINGS {"host":"mongodb://mongodev:27017","database":"celery","taskmeta_collection":"celery_taskmeta"}
celery config Settings(Settings({'BROKER_URL': 'amqp://guest:guest@rabbit1:5672', 'CELERY_INCLUDE': ['celeryworker.tasks'], 'CELERY_ACCEPT_CONTENT': ['json']}, 'BROKER_URL': 'amqp://guest:guest@rabbit1:5672', 'CELERY_MONGODB_BACKEND_SETTINGS': None, 'CELERY_RESULT_BACKEND': None}))
APP_SETTINGS config.DevelopmentConfig
app.config <Config {'ENV': 'development', 'CELERY_BROKER_URL': 'amqp://guest:guest@rabbit1:5672', 'CELERY_MONGODB_BACKEND_SETTINGS': {'host': 'mongodb://mongodev:27017', 'database': 'celery', 'taskmeta_collection': 'celery_taskmeta'}, 'CELERY_RESULT_BACKEND': 'mongodb', 'CELERY_RESULT_SERIALIZER': 'json', }>

-------------- celery@a5ea76b91f77 v4.2.1 (windowlicker)
---- **** -----
--- * ***  * -- Linux-4.9.93-linuxkit-aufs-x86_64-with-debian-9.4 2018-10-29 17:25:27
-- * - **** ---
- ** ---------- [config]
- ** ---------- .> app:         celeryworker:0x7f28e828f668
- ** ---------- .> transport:   amqp://guest:**@rabbit1:5672//
- ** ---------- .> results:     mongodb://
- *** --- * --- .> concurrency: 2 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
 -------------- [queues]
                .> celery           exchange=celery(direct) key=celery

[tasks]
  . celeryworker.tasks.longtime_add

1 个答案:

答案 0 :(得分:0)

我仍然不知道为什么上面的配置不起作用,但是我发现了一种解决方法,可以在应用加载后使用新的配置值名称来更新配置:

app = Celery('celeryworker', broker=os.getenv('CELERY_BROKER_URL'),
              backend=os.getenv('CELERY_RESULT_BACKEND'),
              include=['SGSDevOps.celeryworker.tasks'])
print('app initiated')
app.config_from_object(app_settings)
app.conf.update(accept_content=['json'])
app.conf.update(mongodb_backend_settings=ast.literal_eval(os.getenv('CELERY_MONGODB_BACKEND_SETTINGS')))