yt-dlp-dags/airflow/README-proxy.RU.md
2025-08-26 18:00:55 +03:00

27 KiB
Raw Blame History

Стратегия Управления Прокси и Аккаунтами

В этом документе описывается интеллектуальная стратегия управления ресурсами (прокси и аккаунтами), используемая в ytdlp-ops-server. Цель этой системы — максимизировать процент успешных операций, минимизировать блокировки и обеспечить отказоустойчивость.

Сервер может работать в разных ролях для поддержки распределенной архитектуры, разделяя задачи управления и задачи генерации токенов.


Роли Сервиса и Архитектура

Сервер предназначен для работы в одной из трех ролей, указываемых флагом --service-role:

  • management: Один легковесный экземпляр сервиса, отвечающий за все вызовы API управления.

    • Назначение: Предоставляет централизованную точку входа для мониторинга и управления состоянием всех прокси и аккаунтов в системе.
    • Поведение: Предоставляет только функции управления (getProxyStatus, banAccount и т.д.). Вызовы функций генерации токенов будут завершаться ошибкой.
    • Развертывание: Запускается как один контейнер (ytdlp-ops-management) и напрямую открывает свой порт на хост (например, порт 9091), минуя Envoy.
  • worker: Основная "рабочая лошадка" для генерации токенов и info.json.

    • Назначение: Обрабатывает все запросы на генерацию токенов.
    • Поведение: Реализует полный API, но его функции управления ограничены его собственным server_identity.
    • Развертывание: Запускается как масштабируемый сервис (ytdlp-ops-worker) за балансировщиком нагрузки Envoy (например, порт 9080).
  • all-in-one (По умолчанию): Один экземпляр, который выполняет как управленческие, так и рабочие функции. Идеально подходит для локальной разработки или небольших развертываний.

Эта архитектура позволяет создать надежную, федеративную систему, где воркеры управляют своими ресурсами локально, в то время как центральный сервис предоставляет глобальное представление для управления и мониторинга.


1. Управление Жизненным Циклом Аккаунтов (Cooldown / Resting)

Цель: Предотвратить чрезмерное использование и последующую блокировку аккаунтов, предоставляя им периоды "отдыха" после интенсивной работы.

Как это работает:

Жизненный цикл аккаунта состоит из трех состояний:

  • ACTIVE: Аккаунт активен и используется для выполнения задач. При первом успешном использовании запускается таймер его активности.
  • RESTING: Если аккаунт был в состоянии ACTIVE дольше установленного лимита, AccountManager автоматически переводит его в состояние "отдыха". В этом состоянии Airflow worker не будет выбирать его для новых задач.
  • Возврат в ACTIVE: После завершения периода "отдыха" AccountManager автоматически возвращает аккаунт в состояние ACTIVE, делая его снова доступным.

Конфигурация:

Эти параметры настраиваются при запуске ytdlp-ops-server.

  • --account-active-duration-min: "Время работы" в минутах, которое аккаунт может быть непрерывно активным до перехода в RESTING.
    • Значение по умолчанию: 30 (минут).
  • --account-cooldown-duration-min: "Время отдыха" в минутах, которое аккаунт должен находиться в состоянии RESTING.
    • Значение по умолчанию: 60 (минут).

Где настраивать: Параметры передаются как аргументы командной строки при запуске сервера. При использовании Docker Compose это делается в файле airflow/docker-compose-ytdlp-ops.yaml:

    command:
      # ... другие параметры
      - "--account-active-duration-min"
      - "${ACCOUNT_ACTIVE_DURATION_MIN:-30}"
      - "--account-cooldown-duration-min"
      - "${ACCOUNT_COOLDOWN_DURATION_MIN:-60}"

Вы можете изменить значения по умолчанию, установив переменные окружения ACCOUNT_ACTIVE_DURATION_MIN и ACCOUNT_COOLDOWN_DURATION_MIN в вашем .env файле.

Соответствующие файлы:

  • server_fix/account_manager.py: Содержит основную логику для переключения состояний.
  • ytdlp_ops_server_fix.py: Обрабатывает аргументы командной строки.
  • airflow/docker-compose-ytdlp-ops.yaml: Передает аргументы в контейнер сервера.

2. Умная Стратегия Банов

Цель: Избежать необоснованных банов хороших прокси. Проблема часто может быть в аккаунте, а не в прокси, через который он работает.

Как это работает:

Этап 1: Сначала Бан Аккаунта

  • При возникновении серьезной ошибки, требующей бана (например, BOT_DETECTED или SOCKS5_CONNECTION_FAILED), система применяет санкции только к аккаунту, который вызвал ошибку.
  • Для прокси эта ошибка просто фиксируется как один сбой, но сам прокси не банится и остается в работе.

Этап 2: Бан Прокси по "Скользящему Окну"

  • Прокси блокируется автоматически, только если он демонстрирует систематические сбои с РАЗНЫМИ аккаунтами за короткий промежуток времени.
  • Это является надежным индикатором того, что проблема именно в прокси. ProxyManager на сервере отслеживает это и автоматически банит такой прокси.

Конфигурация:

Эти параметры жестко заданы как константы в коде и для их изменения требуется редактирование файла.

Где настраивать:

  • Файл: server_fix/proxy_manager.py
  • Константы в классе ProxyManager:
    • FAILURE_WINDOW_SECONDS: Временное окно в секундах для анализа сбоев.
      • Значение по умолчанию: 3600 (1 час).
    • FAILURE_THRESHOLD_COUNT: Минимальное общее количество сбоев для запуска проверки.
      • Значение по умолчанию: 3.
    • FAILURE_THRESHOLD_UNIQUE_ACCOUNTS: Минимальное количество уникальных аккаунтов, с которыми произошли сбои, чтобы забанить прокси.
      • Значение по умолчанию: 3.

Соответствующие файлы:

  • server_fix/proxy_manager.py: Содержит логику "скользящего окна" и константы.
  • airflow/dags/ytdlp_ops_worker_per_url.py: Функция handle_bannable_error_callable реализует политику бана "только аккаунт".

Расшифровка Статусов Аккаунтов

Вы можете просмотреть статус всех аккаунтов с помощью DAG ytdlp_mgmt_proxy_account. Статусы имеют следующие значения:

  • ACTIVE: Аккаунт исправен и доступен для использования. По умолчанию, аккаунт считается ACTIVE, если у него не установлен конкретный статус.
  • BANNED: Аккаунт временно отключен из-за повторяющихся сбоев (например, ошибок BOT_DETECTED) или забанен вручную. В статусе будет указано время, оставшееся до его автоматического возвращения в ACTIVE (например, BANNED (active in 55m)).
  • RESTING: Аккаунт использовался в течение длительного времени и находится в обязательном периоде "отдыха" для предотвращения "выгорания". В статусе будет указано время, оставшееся до его возвращения в ACTIVE (например, RESTING (active in 25m)).
  • (Пустой Статус): В более старых версиях аккаунт, у которого были только сбои (и ни одного успеха), мог отображаться с пустым статусом. Это было исправлено; теперь такие аккаунты корректно отображаются как ACTIVE.

3. Сквозной Процесс Ротации: Как Всё Работает Вместе

Этот раздел описывает пошаговый процесс того, как воркер получает аккаунт и прокси для одной задачи, объединяя все вышеописанные стратегии управления.

  1. Инициализация Воркера (ytdlp_ops_worker_per_url)

    • Запускается DAG, инициированный либо оркестратором, либо предыдущим успешным запуском самого себя.
    • Задача pull_url_from_redis извлекает URL из очереди _inbox в Redis.
  2. Выбор Аккаунта (Воркер Airflow)

    • Выполняется задача assign_account.
    • Она генерирует полный список потенциальных ID аккаунтов на основе параметра account_pool (например, от my_prefix_01 до my_prefix_50).
    • Она подключается к Redis и проверяет статус каждого аккаунта из этого списка.
    • Она создает новый временный список, содержащий только те аккаунты, которые не находятся в состоянии BANNED или RESTING.
    • Если итоговый список активных аккаунтов пуст, воркер завершается с ошибкой (если не включено автосоздание).
    • Затем из отфильтрованного списка активных аккаунтов с помощью random.choice() выбирается один.
    • Выбранный account_id передается следующей задаче.
  3. Выбор Прокси (ytdlp-ops-server)

    • Выполняется задача get_token, которая отправляет случайно выбранный account_id в Thrift RPC-вызове на ytdlp-ops-server.
    • На сервере у ProxyManager запрашивается прокси.
    • ProxyManager: a. Обновляет свое внутреннее состояние, загружая статусы всех прокси из Redis. b. Фильтрует список, оставляя только прокси со статусом ACTIVE. c. Применяет политику бана по "скользящему окну", потенциально блокируя прокси, которые недавно слишком часто выходили из строя. d. Выбирает следующий доступный прокси из активного списка, используя индекс round-robin (по кругу). e. Возвращает выбранный proxy_url.
  4. Выполнение и Отчетность

    • Теперь у сервера есть и account_id (от Airflow), и proxy_url (от его ProxyManager).
    • Он приступает к процессу генерации токенов, используя эти ресурсы.
    • По завершении (успешном или неудачном) он сообщает о результате в Redis, обновляя статусы для конкретного аккаунта и прокси, которые были использованы. Это влияет на их счетчики сбоев, таймеры "отдыха" и т.д. для следующего запуска.

Это разделение ответственности является ключевым:

  • Воркер Airflow (задача assign_account) отвечает за случайный выбор активного аккаунта, сохраняя при этом "привязку" (повторно используя тот же аккаунт после успеха).
  • Сервер ytdlp-ops-server отвечает за циклический выбор (round-robin) активного прокси.

4. Автоматический Бан Аккаунтов по Количеству Сбоев

Цель: Автоматически выводить из ротации аккаунты, которые постоянно вызывают ошибки, не связанные с баном (например, неверный пароль, проблемы с авторизацией).

Как это работает:

  • AccountManager отслеживает количество последовательных сбоев для каждого аккаунта.
  • При успешной операции счетчик сбрасывается.
  • Если количество последовательных сбоев достигает заданного порога, аккаунт автоматически банится на определенный срок.

Конфигурация:

Эти параметры задаются в конструкторе класса AccountManager.

Где настраивать:

  • Файл: server_fix/account_manager.py
  • Параметры в __init__ метода AccountManager:
    • failure_threshold: Количество последовательных сбоев до бана.
      • Значение по умолчанию: 5.
    • ban_duration_s: Длительность бана в секундах.
      • Значение по умолчанию: 3600 (1 час).

5. Мониторинг и Восстановление

Как Проверить Статусы

DAG ytdlp_mgmt_proxy_account — это основной инструмент для мониторинга состояния ваших ресурсов. Он подключается напрямую к сервису управления для выполнения действий.

  • ID DAG'а: ytdlp_mgmt_proxy_account
  • Как использовать: Запустите DAG из интерфейса Airflow. Убедитесь, что параметры management_host и management_port правильно указывают на ваш экземпляр сервиса ytdlp-ops-management. Для получения полного обзора установите параметры:
    • entity: all
    • action: list
  • Результат: В логе DAG'а будут отображены таблицы с текущим статусом всех аккаунтов и прокси. Для аккаунтов в состоянии BANNED или RESTING будет показано время, оставшееся до их активации (например, RESTING (active in 45m)). Для прокси будет подсвечено, какой из них является следующим (next) в ротации для конкретного воркера.

Что Произойдет, если Все Аккаунты Будут Забанены или в "Отдыхе"?

Если весь пул аккаунтов станет недоступен (в статусе BANNED или RESTING), система по умолчанию приостановит работу.

  • DAG ytdlp_ops_worker_per_url завершится с ошибкой AirflowException на шаге assign_account, так как пул активных аккаунтов будет пуст.
  • Это остановит циклы обработки. Система будет находиться в состоянии паузы до тех пор, пока аккаунты не будут разбанены вручную или пока не истечет их таймер бана/отдыха. После этого вы сможете перезапустить циклы обработки с помощью DAG'а ytdlp_ops_orchestrator.
  • Граф выполнения DAG ytdlp_ops_worker_per_url теперь явно показывает такие задачи, как assign_account, get_token, ban_account, retry_get_token и т.д., что делает поток выполнения и точки сбоя более наглядными.

Систему можно настроить на автоматическое создание новых аккаунтов, чтобы предотвратить полную остановку обработки.

Автоматическое Создание Аккаунтов при Исчерпании

  • Цель: Обеспечить непрерывную работу конвейера обработки, даже если все аккаунты в основном пуле временно забанены или находятся в "отдыхе".
  • Как это работает: Если параметр auto_create_new_accounts_on_exhaustion установлен в True и пул аккаунтов задан с помощью префикса (а не явного списка), система сгенерирует новый уникальный ID аккаунта, когда обнаружит, что активный пул пуст.
  • Именование новых аккаунтов: Новые аккаунты создаются в формате {prefix}-auto-{уникальный_id}.
  • Конфигурация:
    • Параметр: auto_create_new_accounts_on_exhaustion
    • Где настраивать: В конфигурации DAG ytdlp_ops_orchestrator при запуске.
    • Значение по умолчанию: True.

6. Обработка Сбоев и Политика Повторных Попыток

Цель: Обеспечить гибкое управление поведением системы, когда воркер сталкивается с ошибкой, требующей бана (например, BOT_DETECTED).

Как это работает

Когда задача get_token воркера завершается с ошибкой, требующей бана, поведение системы определяется политикой on_bannable_failure, которую можно настроить при запуске ytdlp_ops_orchestrator.

Конфигурация

  • Параметр: on_bannable_failure
  • Где настраивать: В конфигурации DAG ytdlp_ops_orchestrator.
  • Опции:
    • stop_loop (Самая строгая):
      • Использованный аккаунт банится.
      • URL помечается как сбойный в хэше _fail в Redis.
      • Цикл обработки воркера останавливается. "Линия" обработки становится неактивной.
    • retry_with_new_account (По умолчанию, самая отказоустойчивая):
      • Аккаунт, вызвавший сбой, банится.
      • Воркер немедленно повторяет обработку того же URL с новым, неиспользованным аккаунтом из пула.
      • Если повторная попытка успешна, воркер продолжает свой цикл для обработки следующего URL.
      • Если повторная попытка также завершается сбоем, второй аккаунт и использованный прокси также банятся, и цикл работы воркера останавливается.
    • retry_and_ban_account_only:
      • Похожа на retry_with_new_account, но при втором сбое банится только второй аккаунт, а не прокси.
      • Это полезно, когда вы доверяете своим прокси, но хотите агрессивно перебирать сбойные аккаунты.
    • retry_without_ban (Самая мягкая):
      • Воркер повторяет попытку с новым аккаунтом, но ни аккаунты, ни прокси никогда не банятся.
      • Эта политика полезна для отладки или когда вы уверены, что сбои являются временными и не вызваны проблемами с ресурсами.

Эта политика позволяет системе быть устойчивой к сбоям отдельных аккаунтов, не теряя URL, и в то же время обеспечивает гранулярный контроль над тем, когда банить аккаунты и/или прокси, если проблема сохраняется.


7. Логика Работы Worker DAG (ytdlp_ops_worker_per_url)

Этот DAG является "рабочей лошадкой" системы. Он спроектирован как самоподдерживающийся цикл для обработки одного URL за запуск. Логика обработки сбоев и повторных попыток теперь явно видна в графе задач DAG.

Задачи и их назначение:

  • pull_url_from_redis: Извлекает один URL из очереди _inbox в Redis. Если очередь пуста, DAG завершается со статусом skipped, останавливая эту "линию" обработки.
  • assign_account: Выбирает аккаунт для задачи. Он поддерживает привязку аккаунта (affinity), повторно используя тот же аккаунт из предыдущего успешного запуска в своей "линии". Если это первый запуск или предыдущий был неудачным, он выбирает случайный активный аккаунт.
  • get_token: Основная попытка получить токены и info.json путем вызова ytdlp-ops-server.
  • handle_bannable_error_branch: Задача-развилка, которая запускается в случае сбоя get_token. Она анализирует ошибку и определяет следующий шаг на основе политики on_bannable_failure.
  • ban_account_and_prepare_for_retry: Если разрешен повтор, эта задача банит сбойный аккаунт и выбирает новый.
  • retry_get_token: Вторая попытка получить токен с использованием нового аккаунта.
  • ban_second_account_and_proxy: Если и повторная попытка завершается неудачей, эта задача банит второй аккаунт и использованный прокси.
  • download_and_probe: Если get_token или retry_get_token завершается успешно, эта задача использует yt-dlp для скачивания медиа и ffmpeg для проверки целостности файла.
  • mark_url_as_success: Если download_and_probe завершается успешно, эта задача записывает успешный результат в хэш _result в Redis.
  • handle_generic_failure: Если любая задача завершается с неисправимой ошибкой, эта задача записывает подробную информацию об ошибке в хэш _fail в Redis.
  • decide_what_to_do_next: Финальная задача-развилка, которая решает, продолжать ли цикл (trigger_self_run), остановить его корректно (stop_loop) или пометить как сбойный (fail_loop).
  • trigger_self_run: Задача, которая фактически запускает следующий экземпляр DAG, создавая непрерывный цикл.