videoDownloadTGbot/ARCHITECTURE.md

14 KiB
Raw Blame History

Архитектура системы

Документ описывает внутреннюю архитектуру и принципы работы 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:

- 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. База данных

Схема:

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'ами:
      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 сервису

Развертывание

Локальная разработка

# Основной бот
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 ответа вместо полной загрузки в память