我面临一个问题,无法使用 Celery 在 django 框架中的应用程序中设置定期任务。
我已经尝试了在互联网上找到的解决此问题的所有方法,将代码从我的 MacOS 笔记本电脑传输到 Windows 上的 PC,但似乎没有任何帮助...我使用 celery 中的文档来复制每个步骤定期任务工作,尝试使用其他版本的 Celery、Django-Celery-beat、django-celery-results,但没有任何帮助,所以我不知道我错在代码的哪一部分。
非常感谢任何帮助!
我的应用程序包版本:
芹菜5.3.6
Django 4.0.10
django-celery-beat 2.5.0
django-celery-结果 2.5.1
django-调试工具栏 4.2.0
本町1.1.0
mysql客户端2.2.1
oauthlib 3.2.2
枕头10.1.0
点23.3.2
redis 5.0.1
Python 3.8.8
我的django项目结构:
django-project
├── .vscode
│ └── settings.json
├── myapp
│ ├── admin.py
│ ├── apps.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │
│ ├── models.py
│ ├── signals.py
│ ├── tasks.py
│ ├── templates
│ │ ├── base.html
│ │ ├── home.html
│ │ ├── login.html
│ │ └── skin_list.html
│ ├── tests.py
│ ├── urls.py
│ ├── views.py
│ ├── __init__.py
│ └── __pycache__
├── manage.py
├── django-project
│ ├── asgi.py
│ ├── celeryapp.py
│ ├── config.py
│ ├── pyenv.cfg
│ ├── settings.py
│ ├── urls.py
我没有包含一些文件来使项目结构直观可读。
设置.py:
"""
Django settings for Marketplace_backend project.
Generated by 'django-admin startproject' using Django 4.2.7.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""
from pathlib import Path
import os
from django-project.config import *
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
Debug=True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp',
'debug_toolbar',
'social_django',
'django_celery_beat',
"django_celery_results",
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
"debug_toolbar.middleware.DebugToolbarMiddleware",
'social_django.middleware.SocialAuthExceptionMiddleware',
]
ROOT_URLCONF = 'Marketplace_backend.urls'
# Celery Configuration
# CELERY_BROKER_URL = 'redis://localhost:6379'
# CELERY_RESULT_BACKEND = 'redis://localhost:6379'
CELERY_BROKER_URL = 'redis://127.0.0.1:6379'
CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Europe/Moscow'
from celery.schedules import crontab
# CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'
CELERY_BEAT_SCHEDULE = {
'test': {
'task': 'myapp.tasks.test',
'schedule': crontab(minute='*/1'),
},
}
# CELERY_INCLUDE = ('myapp.tasks',)
# CELERY_IMPORTS = ('myapp.tasks',)
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'social_django.context_processors.backends',
'social_django.context_processors.login_redirect',
'myapp.context_processors.user_social_data',
],
},
},
]
INTERNAL_IPS = [
# ...
"127.0.0.1",
# ...
]
WSGI_APPLICATION = 'django-project.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'app_database',
'USER': 'root',
'PASSWORD': '',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
celeryapp.py:
from celery import Celery
from celery.schedules import crontab
import os
from django.conf import settings
app = Celery('django-project')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django-project.settings')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
django-project 内部文件夹中的init.py:
from __future__ import absolute_import, unicode_literals
from .celeryapp import app as celery_app
__all__ = ('celery_app',)
# Tried this line - didn't help.
from myapp.tasks import test
myapp 中的tasks.py:
# Someone suggested these two lines (2,3) - didn't help
import django
django.setup()
from celery import shared_task
from .models import *
from .views import *
@shared_task(name='test')
def test():
return 'test'
我通过 honcho Procfile 开始一切:
web: python manage.py runserver
celery: celery -A django-project worker --pool=solo -l info
beat: celery -A django-project beat -l info
当我输入 honcho start (启动 django 服务器、celery worker、celerybeat)时,我得到 这个响应:
(django-project) (base) yanik@MacBook-Air django-project % honcho start
17:24:48 system | web.1 started (pid=76511)
17:24:48 system | celery.1 started (pid=76512)
17:24:48 system | beat.1 started (pid=76513)
17:24:48 beat.1 | [2024-01-04 17:24:48,733: INFO/MainProcess] beat: Starting...
17:24:48 celery.1 |
17:24:48 celery.1 | -------------- [email protected] v5.3.6 (emerald-rush)
17:24:48 celery.1 | --- * -----
17:24:48 celery.1 | -- *** ---- macOS-10.16-x86_64-i386-64bit 2024-01-04 17:24:48
17:24:48 celery.1 | - *** --- * ---
17:24:48 celery.1 | - ---------- [config]
17:24:48 celery.1 | - ---------- .> app: django-project:0x7f7a4603ca30
17:24:48 celery.1 | - ---------- .> transport: redis://127.0.0.1:6379//
17:24:48 celery.1 | - ---------- .> results: redis://127.0.0.1:6379/
17:24:48 celery.1 | - *** --- * --- .> concurrency: 8 (prefork)
17:24:48 celery.1 | -- *** ---- .> task events: ON
17:24:48 celery.1 | --- * -----
17:24:48 celery.1 | -------------- [queues]
17:24:48 celery.1 | .> celery exchange=celery(direct) key=celery
17:24:48 celery.1 |
17:24:48 celery.1 |
17:24:48 celery.1 | [tasks]
17:24:48 celery.1 | . django-project.celeryapp.debug_task
17:24:48 celery.1 |
17:24:49 celery.1 | [2024-01-04 17:24:49,145: WARNING/MainProcess] /Users/yanik/.local/share/virtualenvs/django-project-9ZCnhA-p/lib/python3.8/site-packages/celery/worker/consumer/consumer.py:507: CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine
17:24:49 celery.1 | whether broker connection retries are made during startup in Celery 6.0 and above.
17:24:49 celery.1 | If you wish to retain the existing behavior for retrying connections on startup,
17:24:49 celery.1 | you should set broker_connection_retry_on_startup to True.
17:24:49 celery.1 | warnings.warn(
17:24:49 celery.1 |
17:24:49 celery.1 | [2024-01-04 17:24:49,157: INFO/MainProcess] Connected to redis://127.0.0.1:6379//
17:24:49 celery.1 | [2024-01-04 17:24:49,158: WARNING/MainProcess] /Users/yanik/.local/share/virtualenvs/Marketplace_backend-9ZCnhA-p/lib/python3.8/site-packages/celery/worker/consumer/consumer.py:507: CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine
17:24:49 celery.1 | whether broker connection retries are made during startup in Celery 6.0 and above.
17:24:49 celery.1 | If you wish to retain the existing behavior for retrying connections on startup,
17:24:49 celery.1 | you should set broker_connection_retry_on_startup to True.
17:24:49 celery.1 | warnings.warn(
17:24:49 celery.1 |
17:24:49 celery.1 | [2024-01-04 17:24:49,161: INFO/MainProcess] mingle: searching for neighbors
17:24:49 web.1 | Watching for file changes with StatReloader
17:24:50 celery.1 | [2024-01-04 17:24:50,172: INFO/MainProcess] mingle: all alone
17:24:50 celery.1 | [2024-01-04 17:24:50,189: INFO/MainProcess] [email protected] ready.
当 celerybeat 尝试执行周期性任务时,我收到此错误:
20:04:00 beat.1 | [2024-01-01 20:04:00,000: INFO/MainProcess] Scheduler: Sending due task
20:04:00 beat.1 | test (myapp.tasks.test)
20:04:00 celery.1 | [2024-01-01 20:04:00,003: ERROR/MainProcess] Received unregistered task of type 'myapp.tasks.test'.
20:04:00 celery.1 | The message has been ignored and discarded.
20:04:00 celery.1 |
20:04:00 celery.1 | Did you remember to import the module containing this task?
20:04:00 celery.1 | Or maybe you're using relative imports?
20:04:00 celery.1 |
20:04:00 celery.1 | Please see
20:04:00 celery.1 | https://docs.celeryq.dev/en/latest/internals/protocol.html
20:04:00 celery.1 | for more information.
20:04:00 celery.1 |
20:04:00 celery.1 | The full contents of the message body was:
20:04:00 celery.1 | b'[[], {}, {"callbacks": null, "errbacks": null, "chain": null, "chord": null}]' (77b)
20:04:00 celery.1 |
20:04:00 celery.1 | The full contents of the message headers:
20:04:00 celery.1 | {'lang': 'py', 'task': 'myapp.tasks.test', 'id': '332beab6-a3de-4e4a-84f3-59d6041a1b47', 'shadow': None, 'eta': None, 'expires': None, 'group': None, 'group_index': None, 'retries': 0, 'timelimit': [None, None], 'root_id': '332beab6-a3de-4e4a-84f3-59d6041a1b47', 'parent_id': None, 'argsrepr': '()', 'kwargsrepr': '{}', 'origin': 'gen24368@DESKTOP-KNKGMAO', 'ignore_result': False, 'replaced_task_nesting': 0, 'stamped_headers': None, 'stamps': {}}
20:04:00 celery.1 |
20:04:00 celery.1 | The delivery info for this task is:
20:04:00 celery.1 | {'exchange': '', 'routing_key': 'celery'}
20:04:00 celery.1 | Traceback (most recent call last):
20:04:00 celery.1 | File "c:\users\yantb\desktop\django-project\django-project\lib\site-packages\celery\worker\consumer\consumer.py", line 658, in on_task_received
20:04:00 celery.1 | strategy = strategies[type_]
20:04:00 celery.1 | KeyError: 'myapp.tasks.test'
实际上无法解释 celery 如何与 django 配合的技术方面,但似乎没有检测到 django 的设置模块。这就是 celery 没有检测到任务的原因。 我进行了此处建议的更改:https://stackoverflow.com/a/49538946/23181652
基本上,我修改了 celeryworker 和 celerybeat 启动命令,因此 Honcho 的新 Procfile 是:
web: python manage.py runserver
celery: DJANGO_SETTINGS_MODULE=Marketplace_backend.settings celery -A Marketplace_backend worker -l INFO
beat: DJANGO_SETTINGS_MODULE=Marketplace_backend.settings celery -A Marketplace_backend beat -l info
我从 tasks.py 中删除了共享任务名称:
@shared_task
def test():
return 'test'
它成功了! 感谢@wiaterb 为分析提供的灵感!