Все проекты

TTVideo

Сервис загрузки медиа для Telegram

Бот принимает ссылку и присылает файл прямо в чат. Тяжёлая работа вынесена в очереди и отдельные воркеры, поэтому один долгий запрос не задерживает остальные, а о поломке сообщают алерты, которые лежат в репозитории вместе с тестами.

В работе

Чат с ботом TTVideo: отправлена ссылка на ролик TikTok, бот прислал видео и предлагает сохранить звук в MP3 или как видеосообщение.
Ссылка на ролик → готовое видео и выбор дополнительного формата в том же диалоге.
Как устроено
  1. Telegramприсылает обновление на вебхук с секретом
  2. Ботпроверяет секрет и ставит задачу в очередь
  3. Redisдве очереди, видео и музыка, и кэш готовых файлов
  4. Воркеры ×3загрузка и ffmpeg; треки через отдельный движок, по одному
  5. Чатготовый файл уходит пользователю

Рядом

  • PostgreSQLпользователи и их настройки
  • Prometheus и Alertmanagerметрики каждого контейнера, правила с тестами
  • Сторож вебхукапо таймеру сверяет адрес вебхука

Проверяемые решения

  1. Работа разделена по стоимости. Треки идут в отдельную очередь, по одному на воркер, и не занимают слоты видео.

    код

  2. Адрес каждого исходящего запроса проверяется в момент DNS-резолва, на каждом редиректе. Строковую проверку адреса уже обходил IPv4-mapped IPv6.

    тесты

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

    инцидент

  4. Правила алертов хранятся в репозитории и проходят тесты promtool до выкатки.

    тесты

Подробно

Устройство

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

Очереди по стоимости работы

Видео и треки идут в разные очереди. Трек на порядок дороже видео: движок ищет запись в нескольких источниках и проверяет кандидатов. В общей очереди пачка треков заняла бы все слоты, поэтому у музыки своя очередь, одна задача на воркер и свой предел глубины.

Redis работает без вытеснения: при переполнении он отказывает в записи, и очереди встают. Поэтому у каждой очереди заданы лимиты хранения завершённых и упавших задач, а вывод внешних процессов обрезается перед тем, как попасть в причину ошибки.

Исходящие запросы

Адреса для загрузки приходят от третьих сторон. Проверка адреса стоит в момент DNS-резолва и повторяется на каждом редиректе: строковую проверку адреса уже обходил IPv4-mapped IPv6. Прокси из окружения для таких запросов отключён, иначе резолвился бы прокси, а не цель, и проверка молча пропадала бы.

Когда всё выглядит здоровым

Однажды вебхук бота оказался подменён на чужой адрес. Контейнеры при этом были здоровы, а Telegram копил обновления. Теперь сторож по таймеру сверяет адрес вебхука и число ожидающих обновлений, а алерты уходят через отдельного бота. Сам вебхук сторож не переставляет: это спрятало бы подмену, а перезапуск её не лечит.

Правила алертов лежат в репозитории и проходят тесты promtool. Функциональные правила ловят картину «попытки есть, успешных загрузок нет» отдельно по каждой площадке.

Все проекты