Коротка відповідь. «Мікросервіси кращі, бо масштабуються» – відповідь, яка провалює архітектурний раунд. Сильна відповідь звучить інакше: «залежить від структури команд, потреби деплоїти частини незалежно і нерівномірності навантаження – ось як я б вирішував». Мікросервіси – це обмін внутрішньої складності коду на складність розподіленої системи, і цей обмін вигідний далеко не завжди. Нижче – критерії, ціна і формулювання, з яких складається доросла відповідь.

Що це насправді означає

Моноліт – один застосунок, який деплоїться цілком: одна кодова база, один процес збірки, спільна база даних. Виклик між модулями – звичайний виклик функції.

Мікросервіси – система з незалежно деплойованих сервісів, кожен зі своєю зоною відповідальності й, у канонічному варіанті, своїми даними. Виклик між модулями – мережевий запит.

Ключове слово в обох означеннях – деплой, а не розмір коду. Великий застосунок з охайними модулями – все ще моноліт. Два сервіси, які неможливо релізити окремо, бо вони ламають одне одного, – все ще моноліт, лише розподілений і гірший.

Реальні критерії розділення

На співбесіді вартує називати не абстрактне «масштабування», а конкретні сили, які штовхають до розділення:

  • Команди. Коли кілька команд постійно конфліктують в одній кодовій базі й чергах релізів – межі сервісів дають їм автономію. Це організаційний аргумент, і він історично головний.
  • Незалежний деплой. Частина системи змінюється щодня, інша – раз на квартал і вимагає обережності. Розділення дозволяє релізити перше, не ризикуючи другим.
  • Нерівномірне навантаження. Обробка зображень з'їдає CPU, а CRUD-адмінка – ні. Окремий сервіс можна масштабувати окремо, не множачи весь застосунок.
  • Межі домену. Якщо в коді вже є природні межі (замовлення, платежі, повідомлення), які майже не діляться даними, – розріз пройде безболісно. Якщо меж немає, мікросервіси їх не створять – вони лише зроблять кожен неправильний розріз болючим мережевим викликом.
  • Різні технологічні вимоги. Рідше, ніж прийнято думати: окремий рантайм чи мова для одного компонента.

Якщо жоден критерій не спрацював – розділення не дає вигоди, лише ціну.

Чесна ціна мікросервісів

Кожна властивість розподіленої системи, яку моноліт дає безкоштовно, у мікросервісах стає роботою:

  • Мережа замість виклику функції. Затримки, таймаути, ретраї, часткові відмови. Виклик, який не може впасти, перетворюється на виклик, який падає у найцікавіший момент.
  • Консистентність даних. Транзакція через два сервіси – це вже не BEGIN/COMMIT, а саги, компенсації, eventual consistency і питання «що покаже користувач, поки система узгоджується».
  • Спостережуваність. Один стектрейс перетворюється на трасування запиту через п'ять сервісів. Без централізованих логів, трейсингу й метрик дебаг стає археологією.
  • Інфраструктура. CI/CD на кожен сервіс, оркестрація, service discovery, версіонування API між сервісами. Це постійна інженерна вартість, а не одноразова.
  • Локальна розробка. «Підніми п'ятнадцять сервісів, щоб перевірити кнопку» – реальний робочий день у поганому розрізі.

Модульний моноліт: чесна середина

Найкорисніша річ, яку можна сказати на співбесіді: між «великою кулею бруду» і мікросервісами є модульний моноліт – один деплой, але жорсткі внутрішні межі: модулі зі своїми публічними інтерфейсами, заборона лазити в чужі таблиці, залежності лише через контракти.

Це дає дві переваги одразу: більшість організаційних вигод без розподіленої ціни – і дешевий шлях еволюції: модуль із чистою межею можна виділити в сервіс пізніше, коли з'явиться реальна причина. Зворотний шлях – склеїти невдало нарізані мікросервіси назад – значно дорожчий.

Як звучить сильна відповідь

Порівняй. Слабко: «Я б обрав мікросервіси, бо вони скейляться і це сучасний підхід». Сильно:

«Спочатку я б з'ясував три речі: скільки команд працюватиме над системою, чи є частини з різко різним профілем навантаження і чи бачимо ми чіткі доменні межі. Для продукту на одну-дві команди я б почав із модульного моноліта: швидший старт, простіший дебаг, одна транзакційна модель. Якщо згодом, наприклад, обробка медіа почне вимагати окремого масштабування – її модуль уже матиме чисту межу, і виділення в сервіс буде переважно інфраструктурною задачею, а не переписуванням».

Тут є все, що оцінює інтерв'юер: уточнення контексту, критерії, компроміс, план еволюції.

Типові пастки у відповідях кандидатів

  1. Аргумент модою. «Так роблять великі компанії» – у великих компаній сотні команд; їхні проблеми не твої.
  2. Плутання модульності з мікросервісами. Чистий код і межі можливі в одному деплої; мережа – не інструмент наведення порядку.
  3. Ігнорування даних. Кандидат ріже сервіси по контролерах, а на питання «а транзакція між ними як?» – тиша. Розріз проходить по даних, не по ендпоінтах.
  4. «Мікросервіси – це швидше». Мережевий виклик повільніший за виклик функції на порядки. Швидшим може стати масштабування конкретної частини – це інше твердження.
  5. Відсутність шляху назад/вперед. Сильні кандидати описують еволюцію; слабкі – кінцевий стан без маршруту до нього.

Питання, які реально ставлять на співбесіді

  1. «Коли б ти НЕ рекомендував мікросервіси?» – маленька команда, нечіткі доменні межі, ранній продукт, який ще шукає форму: розрізи, зроблені до стабілізації домену, майже гарантовано пройдуть не там.
  2. «Як розділити моноліт, який уже болить?» – спочатку навести межі всередині (модулі, заборона перехресних запитів у чужі таблиці), потім виділяти по одному модулю, починаючи з найменш зв'язаного, з фасадом на час переходу.
  3. «Що робити з транзакцією між двома сервісами?» – чесно: уникати такого розрізу, якщо можливо; якщо ні – сага з компенсаційними діями та ідемпотентними кроками, і явне рішення, що бачить користувач у проміжному стані.
  4. «Спільна база для кількох сервісів – це нормально?» – це найпоширеніший компроміс на практиці й водночас прихований моноліт: незалежність деплою зникає, щойно міграція схеми зачіпає обох. Прийнятно як перехідний етап, небезпечно як кінцевий стан.
  5. «Як тестувати мікросервісну систему?» – піраміда зміщується: більше контрактних тестів між сервісами, менше наскрізних e2e, які стають повільними й крихкими.

Ця тема – класика архітектурного раунду поруч із frontend system design; а вміння вести такі розмови – одна з ключових ознак рівня в переході Middle → Senior. Практичний бік бекенд-питань зібрано в розборі Node.js-співбесіди.

Практичне завдання

Візьми свій поточний або навчальний проєкт і письмово відповідай на три питання: де в ньому реальні доменні межі; який модуль першим захотів би окремого деплою і чому; що конкретно зламається в даних, якщо розрізати саме там. Двадцять хвилин цієї вправи дають більше, ніж десять переглянутих доповідей про «правильну архітектуру».