Первый трай фикса celery

This commit is contained in:
2025-12-02 16:44:19 +03:00
parent 889899080a
commit 3388f787c7
7 changed files with 242 additions and 5 deletions

View File

@@ -2,14 +2,26 @@
help:
@echo "Доступные команды:"
@echo ""
@echo "Development:"
@echo " make dev-up - Запустить development окружение"
@echo " make dev-down - Остановить development окружение"
@echo " make dev-build - Пересобрать development контейнеры"
@echo " make dev-logs - Показать логи development"
@echo ""
@echo "Production:"
@echo " make prod-up - Запустить production окружение"
@echo " make prod-down - Остановить production окружение"
@echo " make prod-build - Пересобрать production контейнеры"
@echo " make prod-logs - Показать логи production"
@echo ""
@echo "Celery (Production):"
@echo " make prod-worker-logs - Логи Celery worker"
@echo " make prod-beat-logs - Логи Celery beat"
@echo " make prod-celery-status - Статус Celery"
@echo " make prod-celery-test - Тест Celery подключения"
@echo ""
@echo "Django:"
@echo " make shell - Открыть Django shell"
@echo " make migrate - Выполнить миграции"
@echo " make createsuperuser - Создать суперпользователя"
@@ -97,3 +109,29 @@ status:
prod-status:
docker-compose -f docker-compose.prod.yaml ps
# Celery команды для production
prod-worker-logs:
docker-compose -f docker-compose.prod.yaml logs -f worker
prod-beat-logs:
docker-compose -f docker-compose.prod.yaml logs -f beat
prod-celery-status:
docker-compose -f docker-compose.prod.yaml exec web uv run celery -A dbapp inspect active
prod-celery-test:
docker-compose -f docker-compose.prod.yaml exec web uv run python test_celery.py
prod-redis-test:
docker-compose -f docker-compose.prod.yaml exec web uv run python check_redis.py
# Celery команды для development
celery-status:
cd dbapp && uv run celery -A dbapp inspect active
celery-test:
cd dbapp && uv run python test_celery.py
redis-test:
cd dbapp && uv run python check_redis.py

View File

@@ -44,8 +44,8 @@ COPY --from=builder /app /app
ENV PYTHONUNBUFFERED=1 \
PATH="/usr/local/bin:$PATH"
# Делаем entrypoint.sh исполняемым
RUN chmod +x /app/entrypoint.sh
# Делаем entrypoint скрипты исполняемыми
RUN chmod +x /app/entrypoint.sh /app/entrypoint-celery.sh
EXPOSE 8000

96
dbapp/check_redis.py Normal file
View File

@@ -0,0 +1,96 @@
#!/usr/bin/env python
"""
Скрипт для проверки подключения к Redis.
Запуск: python check_redis.py
"""
import os
import sys
try:
import redis
except ImportError:
print("❌ Redis библиотека не установлена")
print("Установите: pip install redis")
sys.exit(1)
def check_redis():
"""Проверка подключения к Redis"""
print("=" * 60)
print("ПРОВЕРКА REDIS")
print("=" * 60)
# Получаем URL из переменных окружения
broker_url = os.getenv("CELERY_BROKER_URL", "redis://localhost:6379/0")
cache_url = os.getenv("REDIS_URL", "redis://localhost:6379/1")
print(f"\n1. Broker URL: {broker_url}")
print(f"2. Cache URL: {cache_url}")
# Проверка broker (database 0)
print("\n3. Проверка Celery Broker (db 0)...")
try:
r_broker = redis.from_url(broker_url)
r_broker.ping()
print(" ✓ Подключение успешно")
# Проверка ключей
keys = r_broker.keys("*")
print(f" ✓ Ключей в базе: {len(keys)}")
# Проверка очереди celery
queue_length = r_broker.llen("celery")
print(f" ✓ Задач в очереди 'celery': {queue_length}")
except redis.ConnectionError as e:
print(f" ✗ Ошибка подключения: {e}")
return False
except Exception as e:
print(f" ✗ Ошибка: {e}")
return False
# Проверка cache (database 1)
print("\n4. Проверка Django Cache (db 1)...")
try:
r_cache = redis.from_url(cache_url)
r_cache.ping()
print(" ✓ Подключение успешно")
# Проверка ключей
keys = r_cache.keys("*")
print(f" ✓ Ключей в базе: {len(keys)}")
except redis.ConnectionError as e:
print(f" ✗ Ошибка подключения: {e}")
return False
except Exception as e:
print(f" ✗ Ошибка: {e}")
return False
# Тест записи/чтения
print("\n5. Тест записи/чтения...")
try:
test_key = "test:celery:connection"
test_value = "OK"
r_broker.set(test_key, test_value, ex=10) # TTL 10 секунд
result = r_broker.get(test_key)
if result and result.decode() == test_value:
print(f" ✓ Запись/чтение работает")
r_broker.delete(test_key)
else:
print(f" ✗ Ошибка: ожидалось '{test_value}', получено '{result}'")
return False
except Exception as e:
print(f" ✗ Ошибка: {e}")
return False
print("\n" + "=" * 60)
print("ВСЕ ПРОВЕРКИ ПРОЙДЕНЫ")
print("=" * 60)
return True
if __name__ == "__main__":
success = check_redis()
sys.exit(0 if success else 1)

View File

@@ -160,5 +160,14 @@ LOGGING = {
"level": "INFO",
"propagate": False,
},
"celery.worker": {
"handlers": ["console", "celery_file"],
"level": "INFO",
"propagate": False,
},
},
}
# Force Celery to log to stdout for Docker
CELERY_WORKER_REDIRECT_STDOUTS = True
CELERY_WORKER_REDIRECT_STDOUTS_LEVEL = "INFO"

View File

@@ -0,0 +1,26 @@
#!/bin/bash
set -e
echo "Starting Celery Worker..."
# Ждем PostgreSQL
echo "Waiting for PostgreSQL..."
until PGPASSWORD=$DB_PASSWORD psql -h "$DB_HOST" -U "$DB_USER" -d "$DB_NAME" -c '\q' 2>/dev/null; do
echo "PostgreSQL is unavailable - sleeping"
sleep 1
done
echo "PostgreSQL started"
# Ждем Redis
echo "Waiting for Redis..."
until redis-cli -h redis ping 2>/dev/null; do
echo "Redis is unavailable - sleeping"
sleep 1
done
echo "Redis started"
# Создаем директорию для логов
mkdir -p /app/logs
# Запускаем команду (celery worker или beat)
exec "$@"

68
dbapp/test_celery.py Normal file
View File

@@ -0,0 +1,68 @@
#!/usr/bin/env python
"""
Скрипт для тестирования Celery подключения и задач.
Запуск: python test_celery.py
"""
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dbapp.settings.production')
django.setup()
from celery import current_app
from dbapp.celery import debug_task
def test_celery_connection():
"""Проверка подключения к Celery"""
print("=" * 60)
print("ТЕСТ CELERY ПОДКЛЮЧЕНИЯ")
print("=" * 60)
# Проверка конфигурации
print(f"\n1. Broker URL: {current_app.conf.broker_url}")
print(f"2. Result Backend: {current_app.conf.result_backend}")
# Проверка подключения к брокеру
try:
inspect = current_app.control.inspect()
stats = inspect.stats()
if stats:
print(f"\n3. ✓ Активные workers: {list(stats.keys())}")
for worker, info in stats.items():
print(f" - {worker}: {info}")
else:
print("\n3. ✗ Нет активных workers!")
print(" Убедитесь, что Celery worker запущен:")
print(" docker-compose -f docker-compose.prod.yaml logs worker")
except Exception as e:
print(f"\n3. ✗ Ошибка подключения к брокеру: {e}")
return False
# Проверка зарегистрированных задач
registered_tasks = list(current_app.tasks.keys())
print(f"\n4. Зарегистрированные задачи ({len(registered_tasks)}):")
for task in sorted(registered_tasks):
if not task.startswith('celery.'):
print(f" - {task}")
# Тест простой задачи
print("\n5. Тестирование задачи...")
try:
result = debug_task.delay()
print(f" Task ID: {result.id}")
print(f" Waiting for result...")
output = result.get(timeout=10)
print(f" ✓ Результат: {output}")
except Exception as e:
print(f" ✗ Ошибка выполнения задачи: {e}")
return False
print("\n" + "=" * 60)
print("ВСЕ ТЕСТЫ ПРОЙДЕНЫ")
print("=" * 60)
return True
if __name__ == "__main__":
test_celery_connection()

View File

@@ -21,14 +21,14 @@ services:
image: https://registry.geraltserv.ru/geolocation:latest
env_file:
- .env.prod
#entrypoint: []
command: ["uv", "run", "celery", "-A", "dbapp", "worker", "--loglevel=INFO"]
entrypoint: ["/app/entrypoint-celery.sh"]
command: ["uv", "run", "celery", "-A", "dbapp", "worker", "--loglevel=INFO", "--concurrency=2"]
depends_on:
- db
- redis
- web
volumes:
- ./logs:/app/logs
restart: unless-stopped
redis:
image: redis:7-alpine