Сельдерей: как разделить разные среды с разными рабочими?

Мне нужно направить все задачи определенного экземпляра сайта django в определенную очередь. Моя настройка выглядит следующим образом:

  • несколько веб-серверов, на которых запущен проект Django (1.7)
  • один сервер с работниками сельдерея (3.1.7)
  • Три среды: продакшн, постановка, разработка. Каждая среда работает с разными DJANGO_SETTINGS_MODULE, с разными CELERY_DEFAULT_QUEUE настройками.
  • Один экземпляр Redis в качестве брокера (все в одной базе данных)

На «сервере сельдерея» я запускаю несколько рабочих экземпляров через супервизор (упрощенная конфигурация):

[program:production_queue]
environment=PYTHONPATH=/pth/to/src/:/pth/to/site-packages/,DJANGO_SETTINGS_MODULE=website.settings.production
command=/pth/to/python celery -A website.celery worker --events --queues myserver --loglevel WARNING --concurrency 4 -n [email protected]

[program:staging_queue]
environment=PYTHONPATH=/pth/to/src/:/pth/to/site-packages/,DJANGO_SETTINGS_MODULE=website.settings.staging
command=/pth/to/python celery -A website.celery worker --events --queues myserver_staging --loglevel WARNING --concurrency 1 -n [email protected]

[program:development_queue]
environment=PYTHONPATH=/pth/to/src/:/pth/to/site-packages/,DJANGO_SETTINGS_MODULE=website.settings.development
command=/pth/to/python celery -A website.celery worker --events --queues myserver_development --loglevel INFO --concurrency 1 -n [email protected]

Это работает при осмотре:

$ celery -A website.celery inspect activeues
-> [email protected]: OK
    * {u'exclusive': False, u'name': u'myserver', u'exchange': {u'name': u'celery', u'durable': True, u'delivery_mode': 2, u'passive': False, u'arguments': None, u'type': u'direct', u'auto_delete': False}, u'durable': True, u'routing_key': u'celery', u'no_ack': False, u'alias': None, u'queue_arguments': None, u'binding_arguments': None, u'bindings': [], u'auto_delete': False}
-> [email protected]: OK
    * {u'exclusive': False, u'name': u'myserver_staging', u'exchange': {u'name': u'celery', u'durable': True, u'delivery_mode': 2, u'passive': False, u'arguments': None, u'type': u'direct', u'auto_delete': False}, u'durable': True, u'routing_key': u'celery', u'no_ack': False, u'alias': None, u'queue_arguments': None, u'binding_arguments': None, u'bindings': [], u'auto_delete': False}
-> [email protected]: OK
    * {u'exclusive': False, u'name': u'myserver_development', u'exchange': {u'name': u'celery', u'durable': True, u'delivery_mode': 2, u'passive': False, u'arguments': None, u'type': u'direct', u'auto_delete': False}, u'durable': True, u'routing_key': u'celery', u'no_ack': False, u'alias': None, u'queue_arguments': None, u'binding_arguments': None, u'bindings': [], u'auto_delete': False}

(Имена соответствуют настройкам CELERY_DEFAULT_QUEUE)

website/celery.py содержит основы (импорт пропущен):

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

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

Я ошибаюсь в том, что это был бы хороший способ разделить эти задачи? Все документация по маршрутизации посвящена маршрутизации различных задач в разные очереди, которые мне не нужны. Мне нужно направить все задачи определенного сайта (среды) в определенную очередь. Что я могу сделать, чтобы разделить эти среды?


person Tino    schedule 11.02.2015    source источник
comment
да, я думаю, что вы правы. Вы можете установить очередь по умолчанию как другую очередь в зависимости от окружения. Таким образом, вы можете запускать потребителя для каждой очереди, используя -Q queue_name   -  person itzMEonTV    schedule 13.02.2015
comment
Что ж, это то, что я пытался (см. --queues myserver, который совпадает с -Q myserver), но, как я уже сказал, это не работает.   -  person Tino    schedule 03.11.2015
comment
Приходилось ли вам знакомиться с параметрами fanout_prefix и fanout_patterns при использовании Redis в качестве брокера? docs.celeryproject.org/en/latest/getting- начал / брокеры /   -  person Carl    schedule 09.11.2015
comment
@Carl Я еще не видел такой возможности. Похоже, я могу установить только True. Вы знаете, как это работает? Какой префикс ставит? В документации говорится: вы должны установить параметр транспорта для префикса сообщений, чтобы они были получены только активным виртуальным хостом, но что такое активный виртуальный хост? (Что такое виртуальный хост?) Не могу найти его в документации.   -  person Tino    schedule 12.11.2015


Ответы (2)


Я получил ответ от разработчика Celery здесь: https://github.com/celery/celery/issues/2508, то есть:

Вы должны установить все CELERY_DEFAULT_QUEUE, CELERY_DEFAULT_EXCHANGE и CELERY_DEFAULT_ROUTING_KEY. В противном случае вы получите три очереди, привязанные к одному ключу обмена и маршрутизации.

Или используйте здесь метод, который явно настроит его: http://docs.celeryproject.org/en/latest/userguide/routing.html#changing-the-name-of-the-default-queue

Это работает!

person Tino    schedule 12.12.2015

У меня аналогичная настройка для вас, но мое решение - использовать разных брокеров RabbitMQ для разработки, постановки и производства.

Например, в моем личном файле настроек развития у меня есть:

CELERY_BROKER = "librabbitmq://user:user@my_machine.domain.com/"

В файле производственных настроек у меня есть:

CELERY_BROKER = "librabbitmq://prop:prod@main_cluster.domain.com/"

В моем модуле приложения для сельдерея у меня есть:

app = Celery('App', broker=settings.CELERY_BROKER)

Не знаю, помогает это или нет, но я видел ваш пост на доске пользователей сельдерея, и, поскольку других ответов у вас не было ...

person user3203218    schedule 11.11.2015
comment
Да, именно этим я и закончил: использовал разные базы данных Redis для брокера. Он работает, но мне показалось, что он должен работать с настройкой DEFAULT_QUEUE ;-) - person Tino; 12.11.2015