Python 芹菜收到类型为的未注册任务(运行示例)

Python 芹菜收到类型为的未注册任务(运行示例),python,celery,Python,Celery,我正试着从芹菜文档中运行 我运行:celeryd--loglevel=INFO /usr/local/lib/python2.7/dist-packages/celery/loaders/default.py:64: NotConfigured: No 'celeryconfig' module found! Please make sure it exists and is available to Python. "is available to Python." % (configna

我正试着从芹菜文档中运行

我运行:
celeryd--loglevel=INFO

/usr/local/lib/python2.7/dist-packages/celery/loaders/default.py:64: NotConfigured: No 'celeryconfig' module found! Please make sure it exists and is available to Python.
  "is available to Python." % (configname, )))
[2012-03-19 04:26:34,899: WARNING/MainProcess]  

 -------------- celery@ubuntu v2.5.1
---- **** -----
--- * ***  * -- [Configuration]
-- * - **** ---   . broker:      amqp://guest@localhost:5672//
- ** ----------   . loader:      celery.loaders.default.Loader
- ** ----------   . logfile:     [stderr]@INFO
- ** ----------   . concurrency: 4
- ** ----------   . events:      OFF
- *** --- * ---   . beat:        OFF
-- ******* ----
--- ***** ----- [Queues]
 --------------   . celery:      exchange:celery (direct) binding:celery
tasks.py:

# -*- coding: utf-8 -*-
from celery.task import task

@task
def add(x, y):
    return x + y
运行_task.py:

# -*- coding: utf-8 -*-
from tasks import add
result = add.delay(4, 4)
print (result)
print (result.ready())
print (result.get())
在同一文件夹celeryconfig.py中:

CELERY_IMPORTS = ("tasks", )
CELERY_RESULT_BACKEND = "amqp"
BROKER_URL = "amqp://guest:guest@localhost:5672//"
CELERY_TASK_RESULT_EXPIRES = 300
当我运行“run_task.py”时:

在python控制台上

eb503f77-b5fc-44e2-ac0b-91ce6ddbf153
False
celeryd服务器上的错误

[2012-03-19 04:34:14,913: ERROR/MainProcess] Received unregistered task of type 'tasks.add'.
The message has been ignored and discarded.

Did you remember to import the module containing this task?
Or maybe you are using relative imports?
Please see http://bit.ly/gLye1c for more information.

The full contents of the message body was:
{'retries': 0, 'task': 'tasks.add', 'utc': False, 'args': (4, 4), 'expires': None, 'eta': None, 'kwargs': {}, 'id': '841bc21f-8124-436b-92f1-e3b62cafdfe7'}

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/celery/worker/consumer.py", line 444, in receive_message
    self.strategies[name](message, body, message.ack_log_error)
KeyError: 'tasks.add'

请解释问题所在。

您可以在
芹菜.registry.TaskRegistry
类中看到当前已注册任务的列表。可能是您的celeryconfig(在当前目录中)不在
PYTHONPATH
中,因此celery找不到它并返回默认设置。只需在启动芹菜时明确指定它

celeryd --loglevel=INFO --settings=celeryconfig

您还可以设置
--loglevel=DEBUG
,您可能会立即看到问题。

我认为您需要重新启动工作服务器。我遇到了相同的问题,并通过重新启动来解决。

我遇到了相同的问题:
“接收到类型为..的未注册任务”
的原因是celeryd服务在服务启动时未找到并注册任务(顺便说一句,启动时其列表可见)
/manage.py celeryd--loglevel=info

这些任务应该在设置文件中的
CELERY\u IMPORTS=(“任务”)
中声明。

如果您有一个特殊的
celery\u settings.py
文件,它必须在celeryd服务上声明为
--settings=celery\u settings.py
,正如digivampire所写的那样;我补充说

CELERY_IMPORTS=("mytasks")

在我的
celeryconfig.py
文件中解决此问题。

如果遇到这种错误,可能有很多原因,但我找到的解决方案是,我在/etc/defaults/celeryd中的celeryd配置文件是为标准用途配置的,而不是为我的特定django项目配置的。当我将其转换为中指定的格式时,一切都很好。

使用--settings对我不起作用。我必须使用以下方法才能使其全部正常工作:

celery --config=celeryconfig --loglevel=INFO
以下是添加了芹菜导入的celeryconfig文件:

# Celery configuration file
BROKER_URL = 'amqp://'
CELERY_RESULT_BACKEND = 'amqp://'

CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'America/Los_Angeles'
CELERY_ENABLE_UTC = True

CELERY_IMPORTS = ("tasks",)

我的设置有点棘手,因为我使用supervisor将芹菜作为守护进程启动。

对于我来说,通过确保包含任务的应用包含在django的INSTALLED_APPS设置中,解决了此错误。

我将此行添加到/etc/default/celeryd的解决方案

CELERYD_OPTS="-A tasks"
因为当我运行这些命令时:

celery worker --loglevel=INFO
celery worker -A tasks --loglevel=INFO
只有后一个命令显示任务名称

我也尝试过添加芹菜应用程序行/etc/default/celeryd,但也没有成功

CELERY_APP="tasks"

无论您使用的是
CELERY\u IMPORTS
还是
autodiscover\u tasks
,重要的一点是可以找到任务,并且CELERY中注册的任务名称应与工作人员尝试获取的名称相匹配

当您启动芹菜时,比如说
芹菜工人-A项目--loglevel=DEBUG
,您应该会看到任务的名称。例如,如果在我的
芹菜.py
中有一个
debug_任务
任务

[tasks]
. project.celery.debug_task
. celery.backend_cleanup
. celery.chain
. celery.chord
. celery.chord_unlock
. celery.chunks
. celery.group
. celery.map
. celery.starmap
如果在列表中看不到您的任务,请检查芹菜配置是否正确导入任务,可以在
--设置
--配置
芹菜配置
从对象配置


如果您正在使用芹菜节拍,请确保您在
CELERYBEAT_计划中使用的任务名称
task
与芹菜任务列表中的名称匹配。

我也遇到了这个问题,但不完全相同,仅供参考。由于此装饰器语法,最近的升级导致此错误消息

ERROR/MainProcess]收到类型为“我的服务器检查”的未注册任务。

@task(“我的服务器检查”)

不得不改成

@task()


不知道为什么。

我对django Cellery中的PeriodicTask类有问题,而每次执行触发时启动Cellery worker时,它们的名称都显示得很好:

KeyError:u'my_app.tasks.run'

我的任务是一个名为“CleanUp”的类,而不仅仅是一个名为“run”的方法


当我检查表“django\u periodictask”时,我看到了过时的条目,删除它们解决了这个问题。

我在django应用程序中添加了一些信号处理时,神秘地出现了这个问题。在这样做的过程中,我将应用程序转换为使用AppConfig,这意味着在
已安装的应用程序中,它不是简单地读作
'booking
,而是读作
'booking.app.BookingConfig'

芹菜不明白这意味着什么,所以我添加了,
INSTALLED\u APPS\u WITH\u APPCONFIGS=('booking'),
到我的django设置中,并修改了我的
芹菜.py

app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


我发现我们的一个程序员在其中一个导入中添加了以下行:

os.chdir(<path_to_a_local_folder>)
os.chdir()
这导致芹菜工作者将其工作目录从项目的默认工作目录(可以在其中找到任务)更改为其他目录(无法在其中找到任务)


删除这行代码后,找到并注册了所有任务。

我在芹菜节拍中运行任务时遇到同样的问题。芹菜不喜欢相对导入,因此在我的
celeryconfig.py
中,我必须显式设置完整的包名:

app.conf.beat_schedule = {
   'add-every-30-seconds': {
        'task': 'full.path.to.add',
        'schedule': 30.0,
        'args': (16, 16)
    },
}

只是为了给我的案子加上两分钱

我的路径是
/vagrant/devops/test
,其中包含
app.py
\uuuu init\uuuuuuuuuuuuuuuuuupy

当我运行
cd/vagrant/devops/&&芹菜工人-A test.app.芹菜--loglevel=info
时,我收到了这个错误


但是,当我像
cd/vagrant/devops/test&&cellery worker-A app.cellery--loglevel=info那样运行它时,一切都正常。

cellery不支持相对导入,所以在我的celeryconfig.py中,您需要绝对导入

CELERYBEAT_SCHEDULE = {
        'add_num': {
            'task': 'app.tasks.add_num.add_nums',
            'schedule': timedelta(seconds=10),
            'args': (1, 2)
        }
}

一个非常有用的列表的附加项

我发现芹菜与任务中的错误有关(或者至少我无法跟踪适当的日志条目),而且芹菜没有注册它们。我有很多问题
CELERYBEAT_SCHEDULE = {
        'add_num': {
            'task': 'app.tasks.add_num.add_nums',
            'schedule': timedelta(seconds=10),
            'args': (1, 2)
        }
}
def autodiscover_tasks(self, packages=None, related_name='tasks', force=False):
    """Auto-discover task modules.

    Searches a list of packages for a "tasks.py" module (or use
    related_name argument).

    If the name is empty, this will be delegated to fix-ups (e.g., Django).

    For example if you have a directory layout like this:

    .. code-block:: text

        foo/__init__.py
           tasks.py
           models.py

        bar/__init__.py
            tasks.py
            models.py

        baz/__init__.py
            models.py

    Then calling ``app.autodiscover_tasks(['foo', bar', 'baz'])`` will
    result in the modules ``foo.tasks`` and ``bar.tasks`` being imported.

    Arguments:
        packages (List[str]): List of packages to search.
            This argument may also be a callable, in which case the
            value returned is used (for lazy evaluation).
        related_name (str): The name of the module to find.  Defaults
            to "tasks": meaning "look for 'module.tasks' for every
            module in ``packages``."
        force (bool): By default this call is lazy so that the actual
            auto-discovery won't happen until an application imports
            the default modules.  Forcing will cause the auto-discovery
            to happen immediately.
    """
# test_task.py
@celery.task
def test_task():
    print("Celery Task  !!!!")

# test_task.py
@celery.task(name='tasks.test.test_task')
def test_task():
    print("Celery Task  !!!!")
app = Celery('proj',
             broker='amqp://',
             backend='amqp://',
             include=['proj.tasks'])
celery -A app.celery_module.celeryapp worker --loglevel=info
celery -A celeryapp worker --loglevel=info
LOCAL_APPS = [
'apps.myapp.apps.MyAppConfig']
from django.apps import AppConfig

class MyAppConfig(AppConfig):
    name = 'apps.myapp'

    def ready(self):
        try:
            import apps.myapp.signals  # noqa F401
            import apps.myapp.tasks
        except ImportError:
            pass
./manage.py check
app = Celery('APP_NAME', broker='redis://redis:6379/0', include=['app1.tasks', 'app2.tasks', ...])
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
from django.apps import apps
app.autodiscover_tasks(lambda: [n.name for n in apps.get_app_configs()])