Назад в блог
Инфраструктура
2 мин чтения
aiogramRedis

Чему три Telegram-бота научили меня о состоянии

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

Первым Telegram-ботом, который меня по-настоящему увлёк, был бот анонимного чата: пользователи встают в очередь, находят незнакомца в пару, а бот пересылает сообщения между ними. Очередь я держал в обычном списке Python, а активные пары в словаре. На ноутбуке всё работало безупречно.

Потом я выкатил его на сервер, и почти сразу сломались две вещи. Любой перезапуск, даже рутинный ради небольшой правки, стирал все активные диалоги и опустошал очередь. А когда мне понадобился второй воркер, чтобы справляться с нагрузкой, выяснилось, что общей правды о том, кто с кем в паре, просто нет: у каждого процесса был свой словарь, поэтому двое в «одном» чате могли попасть на разные воркеры и вообще не услышать друг друга.

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

Бот-загрузчик Instagram научил второй половине. Скачивание видео это медленно и неравномерно: приходит ссылка, и загрузка может занять несколько секунд. Сделайте это прямо в обработчике, и весь event loop встанет для всех остальных, как только придут несколько ссылок сразу. Поэтому обработчик почти ничего не делает: проверяет ссылку, кладёт задачу в очередь Celery и возвращается. Воркеры забирают тяжёлую работу из очереди в том темпе, который реально тянут, а ограничение запросов на пользователя стоит в middleware перед всем этим.

К тому моменту, когда я превратил эти паттерны в шаблон на aiogram 3, который переиспользую, ни один из них уже не казался находкой. Это та же форма, что и в любом бэкенде: держите обработчики тонкими, выносите состояние в Redis, выносите тяжёлую работу в очередь. Боты просто хорошо прячут этот урок, потому что наивная версия в памяти отлично выглядит на демонстрации. Она разваливается только тогда, когда ей начинает пользоваться кто-то кроме вас.

Поделиться:Поделиться в Telegram
Ещё статьи