Сельдерей — рабочий только иногда подбирает задачи

#python #django #asynchronous #redis #celery

#python #django #асинхронный #redis #сельдерей

Вопрос:

Я создаю портал для генерации потенциальных клиентов, к которому можно получить доступ онлайн. Пожалуйста, не обращайте внимания на многословность кода, я сейчас много занимаюсь отладкой.

Мой рабочий из сельдерея непоследовательно выполняет назначенные ему задачи, и я не уверен, почему.

Самое странное в этом то, что иногда это работает на 100% идеально: в терминале никогда не бывает явных ошибок.

В настоящее время я нахожусь в DEBUG = TRUE и REDIS в качестве брокера!

команда и ответ рабочего терминала celery start

 celery -A mysite worker -l info --pool=solo
 -------------- celery@DESKTOP-OG8ENRQ v5.0.2 (singularity)
--- ***** -----
-- ******* ---- Windows-10-10.0.19041-SP0 2020-11-09 00:36:13
- *** --- * ---
- ** ---------- [config]
- ** ---------- .> app:         mysite:0x41ba490
- ** ---------- .> transport:   redis://localhost:6379//
- ** ---------- .> results:     redis://localhost:6379/
- *** --- * --- .> concurrency: 12 (solo)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
 -------------- [queues]
                .> celery           exchange=celery(direct) key=celery
[tasks]
  . mysite.celery.debug_task
  . submit

[2020-11-09 00:36:13,899: INFO/MainProcess] Connected to redis://localhost:6379//
[2020-11-09 00:36:14,939: WARNING/MainProcess] c:userscoolepycharmprojectslead_django_retryvenvlibsite-packagesceleryappcontrol.py:48: DuplicateNodenameWarning: Received multiple replies from node name: celery@DESKTOP-OG8ENRQ.
Please make sure you give each node a unique nodename using
the celery worker `-n` option.
  warnings.warn(DuplicateNodenameWarning(

[2020-11-09 00:36:14,939: INFO/MainProcess] mingle: all alone
[2020-11-09 00:36:14,947: INFO/MainProcess] celery@DESKTOP-OG8ENRQ ready.

  

views.py

 class LeadInputView(FormView):
template_name = 'lead_main.html'
form_class = LeadInput

def form_valid(self, form):
    print("I'm at views")
    form.submit()
    print(form.submit)
    return HttpResponseRedirect('./success/')
  

tasks.py

 @task(name="submit")
def start_task(city, category, email):
    print("I'm at tasks!")
    print(city, category, email)
    """sends an email when feedback form is filled successfully"""
    logger.info("Submitted")
    return start(city, category, email)
  

forms.py

 class LeadInput(forms.Form):
    city = forms.CharField(max_length=50)
    category = forms.CharField(max_length=50)
    email = forms.EmailField()

    def submit(self):
        print("I'm at forms!")
        x = (start_task.delay(self.cleaned_data['city'], self.cleaned_data['category'], self.cleaned_data['email']))
        return x
  

celery.py

 from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
app = Celery('mysite')

app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


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

  

settings.py

 BROKER_URL = 'redis://localhost:6379'
CELERY_RESULT_BACKEND = 'redis://localhost:6379'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'UTC'
  

Терминал runserver будет выглядеть примерно так:

 I'm at views
I'm at forms!
<bound method LeadInput.submit of <LeadInput bound=True, valid=True, fields=(city;category;email)>>
  

Но рабочий не говорит, что он что-то подобрал, просто «сельдерей @DESKTOP-OG8ENRQ готов». За исключением случаев, когда это работает … по какой-то причине? Я в недоумении!

Комментарии:

1. как вы запускаете сельдерей? поделитесь своим терминалом и celery.py код

2. @NaqibHakimi Спасибо за ответ! Я обновил свой пост, чтобы включить больше моих celery.py код, а также команда терминала line, которую я использую для запуска моего рабочего.

3. каждому рабочему нужно уникальное имя узла, попробуйте использовать опцию -n. сельдерей -рабочий mysite -l info —pool=solo -n worker2. или убейте старый процесс, а затем повторно запустите его

Ответ №1:

Привет всем, кто это видит. Оказывается, это ошибка с сельдереем (или, может быть, redis?)… по-видимому, многие пользователи Windows сталкиваются с этим. https://github.com/celery/celery/issues/3759

Оказывается, ответ заключается в том, чтобы сделать -P соло при запуске worker. Я не уверен, почему это так… но это решило проблему!

Спасибо, Накиб, за вашу помощь! Ты привел меня к правильному решению кроличьей норы.

Ответ №2:

По умолчанию celery будет использовать имя хоста в качестве имени рабочего, если вы хотите использовать несколько рабочих на одном хосте, затем укажите -n опцию.

 celery -A mysite worker -l info --pool=solo -n worker2@%h
  

Ваш код работает нормально, но задача передается первому рабочему, см.
Дубликатное предупреждение без очевидной причины #2938