#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