#python #django #celery
Celery контролируется by superviser. Есть файл для celery и для beat, но запускаются
3 процесса (worker дублируется). В логах всегда фигурирует Worker-1.
Есть выдержки из логов тут.
Проблема заключается в том, что таски, выполняющиеся каждые 2 минуты, запускаются
вовремя только первые 20-40 минут. Дальше все начинает идти не так. По прошествии очередных
2-х минут, задания перестают выполняться вовремя. Остаются только сообщение отправки
Scheduler: Sending due task contestsapp.tasks.apply_votes
без получения
Received task: contestsapp.tasks.apply_votes[786b5cc6-5b08-40b0-9638-970a5ce6990f]
Таким образом они накапливаются (неясно где, но celery процессы держат 90MB в памяти).
Через некоторое время воркер хватает все невыполненные задания и мгновенно (они примитивные)
выполняет.
В итоге задания с периодом 2 мин выполняются каждые 10 минут по 5 раз (показатели
варьируются). Больше 5-ти одинаковых тасков не скапливается.
В остальном система работает. Отказов и исключений нет, брокер сбрасывался, база
синхронизировалась, PeriodicTask.objects.update(last_run_at=None) не помог, TZ везде
(даже ОС) стоит UTC.
PS
Иногда приходит пара десятков отложенных на дни-недели тасков. Такой "нагрузки" хрупкий
баланс двухминуток обычно не выдерживает, и проявляется эта проблема (но и без них
сценарий всегда один).
Компоненты системы:
Rabbitmq - celery 3
Apache2 - wsgi - Django 1.9.5
Supervisor for celery and beat (but it runs one additional worker )
Файл настроек:
settings.py
CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler"
CELERY_TIMEZONE = 'UTC'
TIME_ZONE = 'UTC'
Пример задачи:
@periodic_task(ignore_result=True, run_every=crontab(minute='*/2'))
def apply_denial():
print('apply_denial')
denialDicts = {id:cache.get(id) for id in cache.keys("denial:*") if cache.ttl(id)<=290}
for k, v in denialDicts.items():
user = Profile.objects.get(id=k[(k.index('denial:') + 7):])
user.denial = (list(set(v) - set(user.denial)) + user.denial)[:300]
user.save()
cache.delete(k)
Копал уже во все стороны...
Ответы
Ответ 1
А вы урл брокера задали??? Типа BROKER_URL = "amqp://user:pass@localhost/queue", где user и pass это логин пароль от раббита, а queue - очередь куда пуляются ваши сообщения P.S если так запускаете воркеры -A project worker --loglevel=INFO -A project worker --loglevel=INFO -A project beat --loglevel=INFO попробуйте заменить на: -A app_celery worker -l info -B -Q "наименование очереди" если никакую очередь явно не используете то -Q не нужно указывать
Комментариев нет:
Отправить комментарий