С чего все началось
Работаю в IT больше 15 лет. Чем только не занимался, но всегда следовал правилу - каждые майские праздники я пытаюсь применить на практике что-то новое.В этом году я прочитал книгу Event Driven Microservices и загорелся потрогать Kafka как настоящий брокер событий, а не сообщений.
Идей было много, но мне хочется проверить все это под реальной нагрузкой, что сразу привело в телеграм боты, где получить +- 1000 пользователей труда не составляет.
Я все детство провозился с ASCII играми в DOS и идея пришла сама собой. В телеграме я нашел кучу текстовых квестов, но с графикой не было ни одного. Я провел небольшое исследование, как телеграм реагирует на большое количество emoji и выявил пару проблем:
- Есть ограничение на 13 символов в строке, до момента, как телега не будет все ломать
- На андроид, начиная с 50 символа телеграм меняет стилистику emoji

Когда с идеей определился, настал момент выбирать технологии к реализации:
- У меня есть кластер Kubernetes и несколько серверов
- Для хранения данных я установил PostgreSQL, так как хорошо его знаю
- Написал несколько скриптов на "Bashsible" для потребностей DevOps
- Установил Kafka. Версия с Zookeeper и без репликации
- В дальнейшем добавил Redis, но об этом позже
- Сервисы решил писать на Java со Spring Boot
- Для хранения и аналитики логов поставил ELK
Я провозился несколько часов, пока не понял в чем дело. Необходимо загрузить в tls секрет всю цепочку сертификатов. Спасибо доброму человеку, написавшего эту статью: Сшиваем SSL-сертификаты
Вторая - это ограничения Telegram. В первой версии я реализовал MMO. Персонажи обновлялись сразу во всех чатах, где их можно увидеть.
Но лимиты телеграма быстро вернули меня в реальность и я решил оставить эту затею. Затем пришла пора входного потока событий. Если изменять сообщение чаще чем раз в секунду, то сразу попадаешь под ошибку подобную этой:
Too Many Requests: "{"ok":false,"error_code":429,"description":"Too Many Requests: retry after 33","parameters":{"retry_after":33}}"
К этому моменту я разбил всю систему на 3 группы микросервисов:
- Получение событий из Telegram. Сервис обладает POST контроллером для получения действий пользователя из чата с ботом. А также Kafka Producer, отправляющего данные сообщения в обработку. Позже, я добавил к этому сервису Redis для проверки частоты кликов пользователя на кнопки в боте
- Обработчики событий. В нее входят:
- Consumer сообщений из входного потока сообщений, и producer в выходной поток сообщений
- Сервисы карты мира
- Объекты для взаимодействия (мобы, NPC, здания, лут и т.д.)
- Пользователи и их характеристики
- Квестовый движок (Состояния, диалоги, скрипты)
- Отправка событий в Telegram. Сервис получает сообщения из выходного потока и отправляет их в телеграм. Попутно проверяя их на лимиты.
Для чего пригодился Redis
Я искал способ на проверку частоты отправки и наткнулся на такую возможность Redis как PX, т.е. время жизни объекта. При получения события я проверяю на наличие объекта по ключу(id чата пользователя), а затем записываю его опять с параметром px = 1000ms.Если при получении события объект в Redis существует, то я игнорирую данное событие.
Ключевые фишки PostgreSQL
PostgreSQL очень помог на этапе создания квестового движка. Я активно использую индексы с условием и функциональные констрейнты.Также, очень помогла и сократила размер кода такая конструкция в запросах как INSERT ... on conflict do
Результат
Я получил горизонтально-масштабируемую систему, позволяющую довольно легко внедрять новый функционал. При повышении нагрузки - я добавляю партиции в топики Kafka и увеличиваю кол-во pod'ов, содержащие consumer’ы.Я накидал небольшой сюжет и опубликовал все это на нескольких ресурсах. Полет нормальный, народ требует продолжения, MMO и PvP
Как продавать шкуры и ловить троллей в Telegram с помощью Kafka, Kubernetes, PostgreSQL и Redis
С чего все началось Работаю в IT больше 15 лет. Чем только не занимался, но всегда следовал правилу - каждые майские праздники я пытаюсь применить на практике что-то новое. В этом году я прочитал...
