Вопрос или проблема
Я запускаю две очереди работников Celery в двух контейнерах Docker. Они запущены из одного и того же изображения. Вот файл docker-compose, показывающий, как я их использую:
syncdata: &celery_worker
image: ${SYNCAPP_IMAGE_TAG?}
depends_on:
syncapi:
condition: service_healthy
env_file:
- .env
environment:
- TZ=Asia/Dhaka
networks:
- es-sync
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- /var/log/syncapp:/es-sync/logs
command: ["scripts/start_syncdata.sh"]
healthcheck:
test: "$$PYTHON_HOME/bin/python -m celery -b $$CELERY_BROKER_URL inspect ping | grep -q 'data'"
start_period: 10s
interval: 10s
timeout: 5s
restart: always
syncadmin:
<<: *celery_worker
command: ["scripts/start_syncadmin.sh"]
healthcheck:
test: "$$PYTHON_HOME/bin/python -m celery -b $$CELERY_BROKER_URL inspect ping | grep -q 'admin'"
start_period: 10s
interval: 10s
timeout: 5s
Скрипт: scripts/start_syncadmin.sh
:
#!/usr/bin/env sh
set -e
exec $PYTHON_HOME/bin/python -m celery -A syncapp.worker:app worker \
--concurrency=4 \
--pool=processes \
--hostname=admin@%h \
--queues=syncapp.tasks.admin_task
Скрипт: scripts/start_syncdata.sh
:
#!/usr/bin/env sh
set -e
exec $PYTHON_HOME/bin/python -m celery -A syncapp.worker:app worker \
--concurrency=1 \
--pool=processes \
--hostname=data@%h \
--queues=syncapp.tasks.data_task
Когда я запускаю контейнеры, я вижу, что состояния смешивания “все поодиночке
” для обоих.
syncadmin-1 | [2024-10-27 14:33:16.779] [pid 1] [INFO] - [celery.worker.consumer.connection]: Подключено к redis://syncredis:6379/0
syncadmin-1 | [2024-10-27 14:33:16.780] [pid 1] [INFO] - [celery.worker.consumer.mingle]: смешивание: поиск соседей
syncadmin-1 | [2024-10-27 14:33:17.786] [pid 1] [INFO] - [celery.worker.consumer.mingle]: смешивание: все поодиночке
syncadmin-1 | [2024-10-27 14:33:17.794] [pid 1] [INFO] - [celery.apps.worker]: admin@15e376d64484 готов.
syncadmin-1 | [2024-10-27 14:33:26.597] [pid 1] [INFO] - [celery.worker.control]: События группы {task} включены удаленно.
Другой контейнер работника производит аналогичные логи.
Некоторые выводы:
- Я также запускаю контейнер flower, который определяет обоих работников как “
В сети
“. Однако на странице/broker
колонкиUnacked
,Ready
,Consumers
иIdle since
всегда показываютN/A
. - Я могу выполнить команду
celery inspect ping
, и похоже, что она находит обоих:-> admin@15e376d64484: ОК pong -> data@3d724eacb46d: ОК pong 2 узла в сети.
- Если я запускаю работников без docker, т.е. из ‘screen’, mingle может обнаруживать друг друга.
- Контейнеры docker запускаются в одной и той же конфигурации хоста и сети.
Я предполагаю, что существуют некоторые недостающие элементы, связанные с обработкой этого внутри контейнеров docker. Это ни в коем случае не влияет на задачи, но как мне решить эту проблему?
Ответ или решение
Проблема обнаружения процессов Celery во время стадии "mingle" в Docker контейнерах
Ваша ситуация с тем, что процессы Celery не могут обнаружить друг друга в контейнерах с Docker, во время стадии "mingle", несмотря на правильную настройку и использование брокера сообщений, имеет несколько возможных причин и решений. Давайте разберем основные аспекты этой проблемы.
1. Групповая связь Celery и Docker
Celery использует механизм "mingle" для обнаружения других рабочих процессов в сети. Во время этой стадии процессы обмениваются сообщениями, чтобы определить, кто доступен. Если процессы не обнаруживают друг друга, это может быть связано с ограничениями сетевой конфигурации Docker:
- Сетевая конфигурация: Убедитесь, что оба контейнера находятся в одной сети Docker. В вашем
docker-compose.yml
вы указалиnetworks: - es-sync
, что является правильным шагом. Проверьте, что не установлены дополнительные параметры безопасности, такие как "network isolation".
2. Подключение к брокеру сообщений
Ваши логи показывают, что оба рабочего процесса успешно подключаются к Redis в качестве брокера сообщений, что является хорошим знаком. Однако, важно убедиться, что оба контейнера могут обращаться друг к другу по имени хоста.
- Проверка DNS: Убедитесь, что DNS в Docker работает корректно. Вы можете попробовать добавить в ваши команды дополнительные флаги, указывающие явный адрес Redis и проверьте, могут ли процессы обмениваться сообщениями по этому адресу.
3. Проблемы с hostname
Вы используете параметр --hostname
в своих командах для запуска рабочий процессов (например, --hostname=data@%h
). Если hostname конфликтует или не соответствует действительности, это может помешать обнаружению.
- Проверка hostname: Попробуйте убрать
@%h
из имен хостов, чтобы использовать более простые и стандартные имена, например, простоadmin
иdata
. Это может помочь упрощенной идентификации между процессами в сети.
4. Проверка конфигурации и сетевых утечек
Поскольку проблемы не наблюдаются, когда вы запускаете Celery вне Docker, это указывает на возможные проблемы с конфигурацией сетевого окружения. Даже если ваши процессы могут ping-друг друга через celery inspect ping
, это не гарантирует, что информация сообщается идеально в контексте обмена сообщений Celery.
- Использование Docker Compose Healthcheck: Убедитесь, что ваши проверки состояния (healthcheck) правильно срабатывают и не останавливают выполнение игровых процессов.
5. Дополнительные шаги для устранения неполадок
- Логи и дебаггинг: Убедитесь, что логи Celery и Docker выводятся должным образом, чтобы получить дополнительную информацию о проблемах соединения.
- Просмотр конфигурации Flower: Flower может показывать данные о процессах, но если у вас есть проблемы с
N/A
в статах, вам стоит исследовать, как Flower подключается к вашим рабочим процессам.
Заключение
Хотя ваша проблема с "mingle" не влияет на выполнение задач, её устранение может улучшить управление рабочими процессами и повысить общую стабильность ваших приложений. Рекомендуется перепроверить сетевые настройки, конфигурацию имен хостов и обеспечить, чтобы оба процесса могли корректно обмениваться сообщениями друг с другом.
Если проблема сохраняется после выполнения всех шагов, рассмотрите возможность обновления версий Docker и Celery, либо проверьте наличие известных ошибок в соответствующих репозиториях.