Как я монолитный проект Tip2Go на микросервисы разделял

Когда проект Tip2Go начал разрастаться, пришлось срочно менять его архитектуру. А так как изначально проект задумывался небольшим и был сделал в формате монолита, то распиливание его на сервисы оказалось интересной задачей!

По поводу проекта, о котором я пару раз упоминал. Мы уже на финишной прямой, им уже даже пользуются наши друзья и знакомые, от которых мы получаем обратную связь и что-то исправляем или дополняем.

Так как Tip2Go изначально задумывался как бот в Telegram и с ограниченным функционалом, я начинал его делать как монолит, который содержит в себе весь функционал. Это реально удобно, когда запаковываешь всё в Docker и для деплоя достаточно выполнить одну команду.

Но с развитием идеи проекта я понял, что если оставлять его монолитным, то придётся непропорционально наращивать мощности сервера, а это, опять же, расходы на содержание. И я принял волевое решение распилить проект на сервисы, которые можно разнести по разным серверам. Благо, что я изначально придерживался современных подходов в программировании и проект, даже будучи монолитом, внутри был очень хорошо спроектирован с соблюдением принципов SOLID.

А это значит, что из проекта можно легко вычленить нужные объекты и достаточно быстро перенести их в другой проект, без ущерба для основного. Всё же, принцип единой ответственности (single responsibility), за который отвечает буква S в аббревиатуре SOLID, очень важен. Ведь, если бы я в объекты добавлял излишний функционал, то выделить их в отдельный сервис так просто не получилось бы.

Итак, что же из себя представляет проект после разделения на сервисы?

Балансировщик на входе, за ним 4 сервиса, база данных на отдельном сервере без внешнего IP, а файлы хранятся в S3.

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

В проекте наружу смотрит только один IP и на нём сидит балансировщик и перенаправляет запросы на внутренние сервисы.

Если запрошена картинка, то запрос перенаправляется на сервис с файлами. Здесь я осуществил давнюю идею с картинками, точнее с проверкой их существования на сервере и возврат заглушки, вместо картинки, если она не найдена.

Если пользователь хочет зайти в панель управления, то ему нужно прежде авторизоваться на основном сервисе и иметь соответствующую роль в системе. В противном случае, пользователя просто перенаправит на страницу основного сервиса.

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

Ну и четвёртый сервис, как раз пользовательский, открыт как для авторизованных, так и для неавторизованных пользователей. Разумеется, для авторизованных пользователей предоставляется больший функционал и возможности. Но и неавторизованные пользователи имеют доступ ко всей бесплатной информации, размещённой на страницах проекта.

Но об этом расскажу в другой раз.