用supervisord运行芹菜无法发现任务

Posted

技术标签:

【中文标题】用supervisord运行芹菜无法发现任务【英文标题】:Running celery with supervisord unable to discover tasks 【发布时间】:2018-06-23 07:27:42 【问题描述】:

我将 celery 4.1.0 与 Django-1.11 和 supervisor 3.3.1 一起使用。由于某种原因,当我通过主管运行 celery worker 时,celery 无法发现应用程序中的任务(在 INSTALLED_APPS 中列出)。当我从命令行运行 celery 时,它 确实 显示任务。例如,当我从命令行运行 celery 时,输出如下:

从命令行运行:

/home/ubuntu/Env/oba/bin/celery worker -A oba -l DEBUG

- ** ---------- .> transport:   amqp://***:**@localhost:***//
- ** ---------- .> results:     disabled://
- *** --- * --- .> concurrency: 1 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** ----- 
 -------------- [queues]
                .> celery           exchange=celery(direct) key=celery


[tasks]
  . celery.accumulate
  . celery.backend_cleanup
  . celery.chain
  . celery.chord
  . celery.chord_unlock
  . celery.chunks
  . celery.group
  . celery.map
  . celery.starmap
  . contact.tasks.send_email_to_admin_for_member
  . contact.tasks.send_email_to_admin_for_visitor

但是当通过 supervisord 运行时,celery 的输出是:

- ** ---------- .> transport:   amqp://***:**@localhost:***//
- ** ---------- .> results:     disabled://
- *** --- * --- .> concurrency: 1 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** ----- 
 -------------- [queues]
                .> celery           exchange=celery(direct) key=celery


[tasks]
  . celery.accumulate
  . celery.backend_cleanup
  . celery.chain
  . celery.chord
  . celery.chord_unlock
  . celery.chunks
  . celery.group
  . celery.map
  . celery.starmap

supervisord 的配置如下所示:

[program:celery]
command=/home/ubuntu/Env/oba/bin/celery -A oba worker -l DEBUG
environment=PATH="/home/ubuntu/Env/oba/bin"
directory=/home/ubuntu/oba
autostart=true
autorestart=true
startretries=3
stdout_logfile=/var/log/celery/%(program_name)s.log
stdout_logfile_maxbytes=50MB
stderr_logfile=/var/log/celery/%(program_name)s.log
stderr_logfile_maxbytes=50MB
user=celery
numprocs=1
process_name=%(program_name)s-%(process_num)s

有趣的是,在尝试检查我看到的已注册任务时:

home/ubuntu/Env/oba/bin/celery -a oba 检查已注册

-> celery@ubuntu-512mb-xxx: OK
    - empty -

myproject/oba/celery.py 中的 celery.py 看起来像这样:

from __future__ import absolute_import
import os
from celery import Celery

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'oba.settings')

from django.conf import settings

app = Celery('oba')

# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

我已经在 contact/tasks.py 中声明了我的任务:

@shared_task
def send_email_to_admin_for_visitor(contactus_visitor_id):
       pass

我不确定为什么它无法自动发现任务。有什么线索吗?

【问题讨论】:

我也遇到了同样的问题。有没有解决的好运气? @Harel 到目前为止没有成功。我不确定这是芹菜问题还是主管问题。所以还没有决定,是否应该向芹菜主管提出罚单。但我想用芹菜做可能会更好。如果我在那里得到一些答案,我一定会更新这张票。 我暂时通过在命令行屏幕会话中运行它,并确保文件上的所有权限都更加宽松,让它暂时工作。但这整件事感觉不对。我已经使用 celery 多年了,这发生在这个使用 v4 的单个项目上(之前主要使用 v3)。 【参考方案1】:

Celery 4.1 的doc 不同:

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings')

app = Celery('proj')

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')

# Load task modules from all registered Django app configs.
app.autodiscover_tasks()


@app.task(bind=True)
def debug_task(self):
    print('Request: 0!r'.format(self.request))

与你的不同之处在于 app.autodiscover_tasks() 的 lambda 函数

如果这不能解决您的问题,您可能需要展示您是如何声明 celery 任务的。

【讨论】:

我也尝试过不使用任何 autodiscover_tasks 参数,但行为仍然相同。我已经编辑了我的问题以显示我是如何声明任务的。【参考方案2】:

我以前遇到过这个问题。我的问题原来是我用来启动 celery worker 的用户(这里是“celery”)没有对我的应用程序的正确访问权限。这意味着用户看不到应用文件夹中的任务。

检查你的应用目录的权限,并授予你的用户正确的权限或使用一个已经有你的应用目录权限的用户来启动worker应该可以解决这个问题。

【讨论】:

以上是关于用supervisord运行芹菜无法发现任务的主要内容,如果未能解决你的问题,请参考以下文章

Django实现异步定时任务

无法在 Heroku 上导入芹菜

芹菜节拍不接周期性任务

芹菜 - 无法获取任务结果

无法获得实时信息的芹菜任务

芹菜:访问上次运行任务的时间?