У меня проблемы с настройкой асинхронных задач с использованием сельдерея.
Я использую django 2.2.1, сельдерей 4.4.0 и django -celery-beat 1.6.0.
Моя цель - запускать указанную c функцию каждые 10 секунд.
Вот как я настроил свой проект:
proj / proj / settings.py
CELERY_BROKER_URL = 'redis://localhost:6379'
CELERY_RESULT_BACKEND = 'redis://localhost:6379'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers.DatabaseScheduler'
CELERY_TIMEZONE = 'UTC'
CELERY_ENABLE_UTC = True
proj / proj / celery.py
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings')
app = Celery('proj')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
proj / proj / init .py
from __future__ import absolute_import, unicode_literals
from .celery import app as celery_app
__all__ = ('celery_app')
proj / proj / tasks.py
@app.task
def team_test():
t_all = Team.objects.all()
for t in t_all:
t.total = random.randint(1, 1000)
t.save()
Теперь с этого момента все, кажется, работает нормально. Я могу добавлять задачи непосредственно в терминале оболочки с помощью команд:
schedule, created = IntervalSchedule.objects.get_or_create(every=10, period=IntervalSchedule.SECONDS)
PeriodicTask.objects.create(interval=schedule, name="team test", task='proj.tasks.team_test')
Я выполнил эту команду со многими тестовыми функциями, и все они затем появляются в моей базе данных. Все идет нормально. Чтобы сбросить рабочих из сельдерея, я затем go в своем командном терминале и запускаю рабочих с командой:
celery -A proj beat -l debug
Снова, я вижу обнадеживающие результаты:
celery beat v4.4.0 (cliffs) is starting.
__ - ... __ - _
LocalTime -> 2020-02-22 17:05:23
Configuration ->
. broker -> redis://localhost:6379//
. loader -> celery.loaders.app.AppLoader
. scheduler -> django_celery_beat.schedulers.DatabaseScheduler
. logfile -> [stderr]@%DEBUG
. maxinterval -> 5.00 seconds (5s)
[2020-02-22 17:05:23,353: DEBUG/MainProcess] Setting default socket timeout to 30
[2020-02-22 17:05:23,353: INFO/MainProcess] beat: Starting...
[2020-02-22 17:05:23,353: DEBUG/MainProcess] DatabaseScheduler: initial read
[2020-02-22 17:05:23,353: INFO/MainProcess] Writing entries...
[2020-02-22 17:05:23,353: DEBUG/MainProcess] DatabaseScheduler: Fetching database schedule
[2020-02-22 17:05:23,360: DEBUG/MainProcess] Current schedule:
<ModelEntry: team test proj.celery.team_test(*[], **{}) <freq: 10.00 seconds>>
<ModelEntry: team test2 proj.tasks.team_test(*[], **{}) <freq: 10.00 seconds>>
<ModelEntry: team test3 app.task.team_test(*[], **{}) <freq: 10.00 seconds>>
<ModelEntry: team test4 tasks.team_test(*[], **{}) <freq: 10.00 seconds>>
<ModelEntry: team test5 . tasks.team_test(*[], **{}) <freq: 10.00 seconds>>
<ModelEntry: team test6 .tasks.team_test(*[], **{}) <freq: 10.00 seconds>>
<ModelEntry: team test7 tasks.team_test(*[], **{}) <freq: 10.00 seconds>>
<ModelEntry: team test8 team_test(*[], **{}) <freq: 10.00 seconds>>
[2020-02-22 17:05:23,608: DEBUG/MainProcess] beat: Ticking with max interval->5.00 seconds
Как видите, у меня запрограммировано много тестовых функций. Когда я смотрю в поле total_run_count
для каждой тестовой функции в моей базе данных, я вижу, что они считаются «запущенными» каждые 10 секунд. Я обычно ожидаю, что эти функции будут работать должным образом до этого момента, но по какой-то причине результат функции не вступает в силу. Это как если бы моя функция вообще не существовала, но она по-прежнему считается «запущенной» функцией.
Я подозреваю, что способ, которым я указал задание для запуска в вызове функции PeriodicTask.objects.create(task=)
, должен быть в неисправность. Боюсь, мой способ вызова моей задачи не относится к функции team_test()
.
Например, я смог запустить PeriodicTask.objects.create(task='zzzzzzzzzzzz')
, хотя эта функция не является частью моего проекта.
У кого-нибудь есть советы по решению этой проблемы?
Большое спасибо.
РЕДАКТИРОВАТЬ:
Я изменил команду, которую использую для получения сельдерея рабочие бегут.
celery -A proj worker --beat -l debug
Насколько я понимаю, нам по-прежнему нужно запускать работника сельдерея, даже если выполняемая задача запускается с помощью «удара». Меня также предупредили, что эту команду нельзя использовать в производстве, так как ее следует выполнять двумя отдельными командами (сначала запустить рабочий, а затем удар).
Это решило мою проблему.