videoDownloadTGbot/ARCHITECTURE.md

346 lines
14 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.

# Архитектура системы
Документ описывает внутреннюю архитектуру и принципы работы Telegram Video Download Bot.
## Общая архитектура
Система состоит из двух основных компонентов:
1. **Основной бот** (`bot.py`) — Telegram бот, обрабатывающий запросы пользователей
2. **VK Downloader Service** (`vk-downloader/`) — отдельный микросервис для скачивания видео с VK
```
┌─────────────────┐
│ Telegram User │
└────────┬────────┘
┌─────────────────────────────────────┐
│ Основной бот (bot.py) │
│ ┌───────────────────────────────┐ │
│ │ YouTube Download Handler │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ Instagram Download Handler │ │
│ └───────────────────────────────┘ │
│ ┌───────────────────────────────┐ │
│ │ VK API Client │──┼──┐
│ └───────────────────────────────┘ │ │
│ ┌───────────────────────────────┐ │ │
│ │ SQLite Database │ │ │
│ │ - Users │ │ │
│ │ - Stats │ │ │
│ └───────────────────────────────┘ │ │
└─────────────────────────────────────┘ │
│ HTTP API
│ POST /download/stream
┌──────────────────────┐
│ VK Downloader │
│ Service │
│ ┌────────────────┐ │
│ │ Flask API │ │
│ └────────────────┘ │
│ ┌────────────────┐ │
│ │ yt-dlp │ │
│ │ (VK only) │ │
│ └────────────────┘ │
└──────────────────────┘
```
## Компоненты системы
### 1. Основной бот (bot.py)
**Технологии:**
- `python-telegram-bot` (v20.7) — асинхронный фреймворк для Telegram Bot API
- `yt-dlp` — библиотека для скачивания видео
- `httpx` — асинхронный HTTP клиент для запросов к VK сервису
- `sqlite3` — база данных для хранения статистики
**Архитектурные решения:**
#### Обработка сообщений
- Асинхронная обработка через `asyncio`
- Каждый пользовательский запрос обрабатывается независимой корутиной
- Параллельная обработка нескольких запросов
#### Скачивание видео
- **YouTube/Instagram**: Прямое скачивание через `yt-dlp` в executor (не блокирует event loop)
- **VK**: HTTP запрос к внешнему микросервису через `httpx`
#### База данных
- SQLite с двумя таблицами:
- `users` — информация о пользователях (chat_id, username, first_name, first_seen, last_seen)
- `stats` — статистика (total_downloads)
- Инициализация при запуске через `init_database()`
- Файл базы: `data/bot.db`
#### Обработка ошибок
- Retry механизм для всех источников (3 попытки по умолчанию)
- Логирование всех ошибок
- Информативные сообщения пользователю
### 2. VK Downloader Service
**Технологии:**
- Flask — веб-фреймворк для REST API
- `yt-dlp` — библиотека для скачивания видео с VK
- Flask-CORS — для поддержки CORS (если нужно)
**API Endpoints:**
1. `GET /health` — проверка работоспособности сервиса
- Возвращает: `{"status": "ok", "service": "vk-downloader"}`
2. `POST /download/stream` — скачивание видео
- Request: `{"url": "https://vk.com/clip-..."}`
- Response: Бинарные данные видео (200 OK) или JSON с ошибкой (400/500)
**Особенности реализации:**
#### Обработка кириллицы
- Имена файлов с кириллицей конвертируются в ASCII для HTTP заголовков
- Оригинальное имя сохраняется в файловой системе
#### Управление файлами
- Временные файлы сохраняются в `downloads/`
- Файлы удаляются после отправки клиенту
- Использование UUID для уникальности имен
#### Ограничения
- Flask dev server (однопоточный) — обрабатывает запросы последовательно
- Для продакшена рекомендуется использовать Gunicorn с несколькими worker'ами
### 3. Определение источника видео
Функция `detect_video_source(url)` анализирует домен URL:
```python
- youtube.com / youtu.be 'youtube'
- instagram.com 'instagram'
- vk.com / vkontakte.ru 'vk'
- иначе 'unknown'
```
### 4. Потоки данных
#### Скачивание с YouTube/Instagram
```
User → Bot → detect_video_source() → download_youtube_video() / download_instagram_video()
yt-dlp (executor) → video file → Telegram API → User
```
#### Скачивание с VK
```
User → Bot → detect_video_source() → download_vk_video()
HTTP POST /download/stream → VK Service
yt-dlp → video file → HTTP Response (binary)
Bot receives binary → saves to disk → Telegram API → User
```
### 5. База данных
**Схема:**
```sql
CREATE TABLE users (
chat_id INTEGER PRIMARY KEY,
username TEXT,
first_name TEXT,
first_seen TEXT NOT NULL,
last_seen TEXT NOT NULL
);
CREATE TABLE stats (
id INTEGER PRIMARY KEY CHECK (id = 1),
total_downloads INTEGER DEFAULT 0
);
```
**Операции:**
- `add_user()` — добавление/обновление пользователя (при каждом взаимодействии)
- `get_total_users()` — получение количества уникальных пользователей
- `increment_downloads()` — увеличение счетчика скачанных видео
- `get_total_downloads()` — получение количества скачанных видео
**Персистентность:**
- База хранится в `data/bot.db` на хосте
- Монтируется как volume в Docker
- Сохраняется между перезапусками контейнера
## Docker архитектура
### Основной бот
**Образ:**
- Базовый: `python:3.11-slim`
- Зависимости: `ffmpeg`, `wget`
- Python пакеты из `requirements.txt`
**Volumes:**
- `./video:/app/video` — временные файлы видео
- `./instagram_cookies.txt:/app/instagram_cookies.txt` — cookies для Instagram
- `./data:/app/data:Z` — база данных (SELinux relabel)
**Network:**
- `network_mode: host` — для доступа к VK сервису через localhost
### VK Downloader Service
**Образ:**
- Базовый: `python:3.11-slim`
- Зависимости: `ffmpeg`, `wget`
- Python пакеты: Flask, flask-cors, yt-dlp, requests
**Volumes:**
- `./downloads:/app/downloads` — временные файлы
**Ports:**
- `5555:5000` — внешний порт 5555, внутренний 5000
**Network:**
- Отдельная сеть `vk_network` (можно использовать host network для доступа)
## Безопасность
### Переменные окружения
- Токен бота хранится в `.env` (не коммитится в Git)
- Cookies для Instagram хранятся в файле (не коммитится)
### Ограничения доступа
- VK сервис доступен только по указанному IP/URL
- Нет аутентификации между ботом и VK сервисом (можно добавить API key)
### Файловая система
- Временные файлы удаляются после отправки
- Cookies файл монтируется read-only (опционально)
## Масштабирование
### Текущие ограничения
1. **Основной бот:**
- Один экземпляр (можно запустить несколько с разными токенами)
- Параллельная обработка запросов ограничена ресурсами CPU/сети
2. **VK сервис:**
- Flask dev server — последовательная обработка
- Один экземпляр контейнера
### Рекомендации для масштабирования
1. **VK сервис:**
- Использовать Gunicorn с несколькими worker'ами:
```bash
gunicorn -w 4 -b 0.0.0.0:5000 app:app
```
- Горизонтальное масштабирование: несколько контейнеров за nginx/HAProxy
- Load balancing для распределения нагрузки
2. **Основной бот:**
- Webhook режим вместо polling (для больших нагрузок)
- Кеширование информации о видео
- Очередь задач (Celery) для скачивания
3. **База данных:**
- Миграция на PostgreSQL для многопользовательской нагрузки
- Connection pooling
## Мониторинг
### Логирование
- Все компоненты логируют в stdout/stderr
- Docker автоматически собирает логи
- Уровни: INFO, WARNING, ERROR
### Метрики (можно добавить)
- Количество запросов в секунду
- Время обработки запроса
- Количество ошибок
- Размер скачанных файлов
### Health checks
- VK сервис: `GET /health`
- Основной бот: проверка через статус контейнера
## Производительность
### Оптимизации
1. **Асинхронная обработка:**
- Основной бот использует asyncio для неблокирующих операций
- yt-dlp запускается в executor для YouTube/Instagram
2. **Временные файлы:**
- Хранение в памяти (tmpfs) для быстрого доступа (опционально)
- Автоматическая очистка после отправки
3. **Кеширование:**
- Можно добавить кеш информации о видео (title, duration)
- Кеш для часто запрашиваемых видео
### Узкие места
1. **VK сервис:**
- Последовательная обработка запросов
- Скачивание файла перед отправкой (занимает память)
2. **Сеть:**
- Зависимость от скорости интернета
- Задержки при обращении к внешнему VK сервису
## Развертывание
### Локальная разработка
```bash
# Основной бот
docker compose up -d
# VK сервис
cd vk-downloader && docker compose up -d
```
### Продакшен (раздельное развертывание)
**Хост 1 (с VPN):**
- Основной бот
- VPN для доступа к YouTube/Instagram
- `.env`: `VK_DOWNLOADER_URL=http://<host2_ip>:5555`
**Хост 2 (без VPN):**
- VK Downloader Service
- Доступен по IP для хоста 1
- Можно масштабировать горизонтально
### CI/CD (опционально)
1. Автоматический build Docker образов
2. Тестирование перед деплоем
3. Автоматический деплой при коммите в main
## Будущие улучшения
1. **Аутентификация между сервисами:**
- API key для VK сервиса
- JWT токены
2. **Очередь задач:**
- Celery/RQ для фоновой обработки
- Retry механизм через очередь
3. **Мониторинг:**
- Prometheus метрики
- Grafana дашборды
4. **Улучшение VK сервиса:**
- Переход на FastAPI (более производительный)
- Поддержка WebSockets для прогресса
- Stream ответа вместо полной загрузки в память