【问题标题】:Django+Celery in Heroku not executing async taskHeroku中的Django + Celery不执行异步任务
【发布时间】:2016-12-13 00:04:42
【问题描述】:

我在 Heroku 有 Django+Celery,Celery 设置为:

import djcelery
djcelery.setup_loader()
BROKER_URL = "django://"  # tell kombu to use the Django database as the message queue
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'
CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend'
CELERY_ALWAYS_EAGER = False
CELERY_TIMEZONE = 'Europe/Madrid'

我在tasks.py 中定义了 2 个任务,一个是周期性的,另一个是在异步调用上执行的:

@task
def test_one_shot():
    print "One shot"

@periodic_task(run_every=crontab(minute="*/5"))
def test_periodic():
    print "Periodic"

Heroku 配置有一个主 web worker 和一个辅助 worker:

web: gunicorn config.wsgi:application ON
worker: python manage.py celery worker -B -l info ON

使用此设置,我运行test_one_shot 任务如下:

test_one_shot.apply_async(eta=datetime.now()+timedelta(minutes=2))

虽然它在 heroku 日志中显示为已注册:

Received task: test.tasks.test_one_shot[f29c609d-b6e8-45d4-808d-2ca690f029af] eta:[2016-08-07 00:09:30.262362+02:00]

它永远不会执行。另一方面,周期性任务test_periodic 按预期执行。我做错了什么?

谢谢!

编辑:由于日期时间感知问题,已执行的任务未出现在日志中。但是,当以编程方式调用任务时,它永远不会执行。

【问题讨论】:

  • 你需要调试它。可能是您在任务中遇到错误,并且它不会在异步任务上显示错误。
  • @levi 你会如何调试它?我已经在测试一个函数,它只是一个打印语句,并直接查看 celery worker 的 heroku 日志(什么都没有出现)。
  • 这里是调试芹菜任务的方法docs.celeryproject.org/en/latest/tutorials/debugging.html

标签: django heroku celery django-celery


【解决方案1】:

我最终在this guide 之后将 celery 后端更改为在 Heroku 中使用 RabbitMQ,问题得到解决。

基本上,我在 Heroku 上安装了 RabbitMQ:

$ heroku addons:add cloudamqp

并为其设置新配置:

import djcelery
djcelery.setup_loader()
CELERY_TIMEZONE = 'Europe/Madrid'

BROKER_URL = env("CLOUDAMQP_URL", default="django://")
BROKER_POOL_LIMIT = 1
BROKER_CONNECTION_MAX_RETRIES = None

CELERY_TASK_SERIALIZER = "json"
CELERY_ACCEPT_CONTENT = ["json", "msgpack"]
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'
CELERY_ALWAYS_EAGER = False

if BROKER_URL == "django://":
    INSTALLED_APPS += ("kombu.transport.django",)

【讨论】:

    最近更新 更多