Як я монолітний проєкт Tip2Go на мікросервіси розділяв
Коли проєкт Tip2Go почав розростатися, довелося терміново змінювати його архітектуру. Оскільки спочатку проєкт задумувався невеликим і був зроблений у форматі моноліту, то розділення його на сервіси виявилося цікавою задачею!
Щодо проєкту, про який я кілька разів згадував. Ми вже на фінішній прямій, ним вже навіть користуються наші друзі та знайомі, від яких ми отримуємо зворотний зв'язок і щось виправляємо або доповнюємо.
Оскільки Tip2Go спочатку задумувався як бот у Telegram з обмеженим функціоналом, я починав його робити як моноліт, що містить у собі весь функціонал. Це дійсно зручно, коли пакуєш усе в Docker і для деплою достатньо виконати одну команду.
Але з розвитком ідеї проєкту я зрозумів, що якщо залишати його монолітним, то доведеться непропорційно нарощувати потужності сервера, а це, знову ж таки, витрати на утримання. І я прийняв вольове рішення розділити проєкт на сервіси, які можна рознести по різних серверах. На щастя, я спочатку дотримувався сучасних підходів у програмуванні і проєкт, навіть будучи монолітом, всередині був дуже добре спроєктований із дотриманням принципів SOLID.
А це означає, що з проєкту можна легко виокремити потрібні об'єкти і досить швидко перенести їх в інший проєкт, без шкоди для основного. Все ж, принцип єдиної відповідальності (single responsibility), за який відповідає літера S в абревіатурі SOLID, дуже важливий. Адже, якби я в об'єкти додавав зайвий функціонал, то виділити їх в окремий сервіс так просто не вдалося б.
Отже, що ж із себе представляє проєкт після розділення на сервіси?
Балансувальник на вході, за ним 4 сервіси, база даних на окремому сервері без зовнішнього IP, а файли зберігаються в S3.
І виявилося, що така архітектура обходиться майже вдвічі дешевше одного сервера. І це не враховуючи того, що такий варіант є ще й більш гнучким і надійним, порівняно з монолітом.
У проєкті назовні дивиться тільки один IP і на ньому сидить балансувальник, який перенаправляє запити на внутрішні сервіси.
Якщо запитано картинку, то запит перенаправляється на сервіс із файлами. Тут я реалізував давню ідею з картинками, точніше з перевіркою їх існування на сервері і повернення заглушки, замість картинки, якщо вона не знайдена.
Якщо користувач хоче зайти в панель управління, то йому потрібно спочатку авторизуватися на основному сервісі і мати відповідну роль у системі. В іншому випадку, користувача просто перенаправить на сторінку основного сервісу.
Для бота, а ми про нього не забули і він теж є в проєкті, також винесено окремий сервіс, доступ до якого можливий тільки з певних IP адрес, в іншому випадку користувач знову ж таки буде перенаправлений, але цього разу на сторінку запуску бота.
Ну і четвертий сервіс, якраз користувацький, відкритий як для авторизованих, так і для неавторизованих користувачів. Звісно, для авторизованих користувачів надається більший функціонал і можливості. Але й неавторизовані користувачі мають доступ до всієї безкоштовної інформації, розміщеної на сторінках проєкту.
Але про це розповім іншим разом.