Files
dbstorage/ASYNC_LYNGSAT_GUIDE.md

421 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Руководство по асинхронному заполнению данных Lyngsat
## Обзор
Система заполнения данных Lyngsat теперь работает асинхронно с использованием Celery. Это позволяет:
- Не блокировать веб-интерфейс во время долгих операций
- Отслеживать прогресс выполнения задачи в реальном времени
- Просматривать детальные логи обработки
- Получать уведомления о завершении задачи
## Архитектура
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Django │─────▶│ Celery │─────▶│ Redis │
│ Web App │ │ Worker │ │ Broker │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
│ ▼
│ ┌─────────────┐
└─────────────▶│ PostgreSQL │
│ Database │
└─────────────┘
```
## Установка и настройка
### 1. Установка зависимостей
```bash
pip install -r requirements.txt
```
Новые зависимости:
- `celery>=5.4.0` - асинхронная обработка задач
- `django-celery-results>=2.5.1` - хранение результатов в БД
### 2. Применение миграций
```bash
cd dbapp
python manage.py migrate
```
Это создаст таблицы для хранения результатов Celery.
### 3. Запуск Redis
Redis используется как брокер сообщений для Celery.
#### Вариант 1: Docker Compose (рекомендуется)
```bash
docker-compose up -d redis
```
#### Вариант 2: Локальная установка
```bash
# Ubuntu/Debian
sudo apt-get install redis-server
sudo systemctl start redis
# macOS
brew install redis
brew services start redis
# Проверка
redis-cli ping
# Должно вернуть: PONG
```
### 4. Запуск FlareSolver
FlareSolver необходим для обхода защиты Cloudflare.
```bash
docker-compose up -d flaresolverr
```
Или отдельно:
```bash
docker run -d -p 8191:8191 --name flaresolverr ghcr.io/flaresolverr/flaresolverr:latest
```
### 5. Запуск Celery Worker
#### Вариант 1: Используя скрипт
```bash
cd dbapp
./start_celery_worker.sh
```
#### Вариант 2: Напрямую
```bash
cd dbapp
celery -A dbapp worker --loglevel=info
```
#### Вариант 3: В фоновом режиме (Linux/macOS)
```bash
cd dbapp
celery -A dbapp worker --loglevel=info --logfile=logs/celery_worker.log --detach
```
## Использование
### 1. Запуск задачи через веб-интерфейс
1. Откройте страницу действий: `http://localhost:8000/actions/`
2. Нажмите "Заполнить данные Lyngsat"
3. Выберите спутники и регионы
4. Нажмите "Заполнить данные"
5. Вы будете перенаправлены на страницу отслеживания прогресса
### 2. Отслеживание прогресса
На странице статуса задачи вы увидите:
- **Прогресс-бар** с процентом выполнения
- **Текущий статус** (например, "Обработка Astra 4A...")
- **Состояние задачи** (PENDING, PROGRESS, SUCCESS, FAILURE)
- **Результаты** после завершения:
- Количество обработанных спутников
- Количество обработанных источников
- Количество созданных записей
- Количество обновленных записей
- Список ошибок (если есть)
Страница автоматически обновляется каждые 2 секунды.
### 3. Просмотр логов
Логи Celery worker содержат детальную информацию о процессе:
```bash
# Просмотр логов в реальном времени
tail -f dbapp/logs/celery_worker.log
# Поиск по логам
grep "Task" dbapp/logs/celery_worker.log
grep "ERROR" dbapp/logs/celery_worker.log
```
Формат логов:
```
[2024-01-15 10:30:45: INFO/MainProcess][lyngsatapp.fill_lyngsat_data_async(abc123)] [Task abc123] Начало обработки данных Lyngsat
[2024-01-15 10:30:45: INFO/MainProcess][lyngsatapp.fill_lyngsat_data_async(abc123)] [Task abc123] Спутники: Astra 4A, Hotbird 13G
[2024-01-15 10:30:46: INFO/MainProcess][lyngsatapp.fill_lyngsat_data_async(abc123)] [Task abc123] Получено данных по 2 спутникам
[2024-01-15 10:31:00: INFO/MainProcess][lyngsatapp.fill_lyngsat_data_async(abc123)] [Task abc123] Обработка спутника 1/2: Astra 4A
```
## Технические детали
### Структура задачи
**Файл**: `dbapp/lyngsatapp/tasks.py`
```python
@shared_task(bind=True, name='lyngsatapp.fill_lyngsat_data_async')
def fill_lyngsat_data_task(self, target_sats, regions=None):
# Логирование начала
# Обновление прогресса
# Вызов функции заполнения
# Сохранение результата в кеш
# Обработка ошибок
```
### Обновление прогресса
Функция `fill_lyngsat_data` теперь принимает callback `update_progress`:
```python
def update_progress(current, total, status):
self.update_state(
state='PROGRESS',
meta={
'current': current,
'total': total,
'status': status
}
)
```
### API для проверки статуса
**Endpoint**: `/api/lyngsat-task-status/<task_id>/`
**Ответ**:
```json
{
"task_id": "abc123",
"state": "PROGRESS",
"status": "Обработка Astra 4A...",
"current": 1,
"total": 2,
"percent": 50
}
```
### Логирование
Используется стандартный модуль `logging` Python:
```python
import logging
logger = logging.getLogger(__name__)
logger.info(f"[Task {task_id}] Начало обработки")
logger.debug(f"[Task {task_id}] Детальная информация")
logger.warning(f"[Task {task_id}] Предупреждение")
logger.error(f"[Task {task_id}] Ошибка", exc_info=True)
```
## Настройки Celery
**Файл**: `dbapp/dbapp/settings/base.py`
```python
# Брокер сообщений
CELERY_BROKER_URL = 'redis://localhost:6379/0'
# Хранение результатов
CELERY_RESULT_BACKEND = 'django-db'
# Таймауты
CELERY_TASK_TIME_LIMIT = 30 * 60 # 30 минут
CELERY_TASK_SOFT_TIME_LIMIT = 25 * 60 # 25 минут
# Отслеживание прогресса
CELERY_TASK_TRACK_STARTED = True
```
## Мониторинг и отладка
### Flower - веб-интерфейс для мониторинга Celery
Установка:
```bash
pip install flower
```
Запуск:
```bash
celery -A dbapp flower
```
Откройте: `http://localhost:5555`
### Проверка статуса задачи через Django shell
```python
python manage.py shell
from celery.result import AsyncResult
task_id = 'abc123'
task = AsyncResult(task_id)
print(f"State: {task.state}")
print(f"Info: {task.info}")
print(f"Result: {task.result}")
```
### Очистка старых результатов
```bash
# Удалить результаты старше 1 дня
python manage.py celery_results_cleanup --days=1
```
## Решение проблем
### Проблема: Worker не запускается
**Решение**:
1. Проверьте, что Redis запущен: `redis-cli ping`
2. Проверьте настройки в `.env`: `CELERY_BROKER_URL`
3. Проверьте логи: `tail -f logs/celery_worker.log`
### Проблема: Задача зависла в состоянии PENDING
**Решение**:
1. Проверьте, что worker запущен: `ps aux | grep celery`
2. Перезапустите worker
3. Проверьте соединение с Redis
### Проблема: Задача завершается с ошибкой
**Решение**:
1. Проверьте логи worker
2. Проверьте, что FlareSolver запущен: `curl http://localhost:8191/v1`
3. Проверьте, что спутники существуют в базе данных
### Проблема: Прогресс не обновляется
**Решение**:
1. Откройте консоль браузера (F12) и проверьте ошибки
2. Проверьте, что API endpoint доступен: `/api/lyngsat-task-status/<task_id>/`
3. Очистите кеш браузера
## Производственное развертывание
### Systemd сервис для Celery Worker
Создайте файл `/etc/systemd/system/celery-worker.service`:
```ini
[Unit]
Description=Celery Worker for Django Lyngsat
After=network.target redis.service
[Service]
Type=forking
User=www-data
Group=www-data
WorkingDirectory=/path/to/dbapp
Environment="PATH=/path/to/venv/bin"
ExecStart=/path/to/venv/bin/celery -A dbapp worker --loglevel=info --logfile=/var/log/celery/worker.log --detach
ExecStop=/path/to/venv/bin/celery -A dbapp control shutdown
Restart=always
[Install]
WantedBy=multi-user.target
```
Запуск:
```bash
sudo systemctl daemon-reload
sudo systemctl enable celery-worker
sudo systemctl start celery-worker
sudo systemctl status celery-worker
```
### Supervisor (альтернатива)
Установка:
```bash
sudo apt-get install supervisor
```
Конфигурация `/etc/supervisor/conf.d/celery.conf`:
```ini
[program:celery-worker]
command=/path/to/venv/bin/celery -A dbapp worker --loglevel=info
directory=/path/to/dbapp
user=www-data
autostart=true
autorestart=true
stdout_logfile=/var/log/celery/worker.log
stderr_logfile=/var/log/celery/worker_error.log
```
Запуск:
```bash
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start celery-worker
```
## Дополнительные возможности
### Периодические задачи (Celery Beat)
Для автоматического обновления данных по расписанию:
1. Установите `django-celery-beat`:
```bash
pip install django-celery-beat
```
2. Добавьте в `INSTALLED_APPS`:
```python
INSTALLED_APPS = [
...
'django_celery_beat',
]
```
3. Примените миграции:
```bash
python manage.py migrate django_celery_beat
```
4. Создайте периодическую задачу через админ-панель Django
5. Запустите beat scheduler:
```bash
celery -A dbapp beat --loglevel=info
```
### Уведомления по email
Добавьте в задачу отправку email при завершении:
```python
from django.core.mail import send_mail
@shared_task(bind=True)
def fill_lyngsat_data_task(self, target_sats, regions=None):
# ... обработка ...
# Отправка email
send_mail(
'Задача Lyngsat завершена',
f'Обработано {stats["total_satellites"]} спутников',
'noreply@example.com',
['admin@example.com'],
)
```
## Заключение
Асинхронная обработка данных Lyngsat обеспечивает:
- ✅ Неблокирующий веб-интерфейс
- ✅ Отслеживание прогресса в реальном времени
- ✅ Детальное логирование
- ✅ Масштабируемость (можно запустить несколько workers)
- ✅ Надежность (автоматический retry при ошибках)
Для получения дополнительной помощи обратитесь к документации:
- [Celery Documentation](https://docs.celeryproject.org/)
- [Django Celery Results](https://django-celery-results.readthedocs.io/)