Мікросервіс — це невеликий автономний компонент програмної системи, який відповідає за одну бізнес-здатність, працює у власному процесі й спілкується з іншими службами через чітко описаний програмний інтерфейс, найчастіше HTTP API. Його можна зібрати, протестувати, розгорнути й масштабувати окремо від решти продукту. Саме ця незалежність і відрізняє його від модуля всередині моноліту, де зміна в одному місці змушує збирати й випускати всю програму цілком.
Мікросервісна архітектура збирає застосунок як набір таких служб, а не як один великий виконуваний файл. Кожна служба має власний цикл релізів, часто власне сховище даних і команду, яка її будує й експлуатує. Зв’язок між ними навмисно «тонкий»: контракт API, черга повідомлень, подія — і жодного спільного об’єкта в пам’яті.
Цей підхід не є обов’язковим етапом «зрілості» продукту. Це технічне й організаційне рішення для систем, яким уже тісно в одній кодовій базі: коли команди блокують одна одну релізами, коли пік навантаження падає лише на оплату чи каталог, коли відмова модуля не повинна гасити весь сайт.
Як мікросервіс працює зсередини
У моноліті виклик функції — це стрибок у межах одного процесу: швидко, дешево, з спільною транзакцією бази. Мікросервіс ламає цю звичку. Виклик сусіда стає мережевим запитом. Між «створити замовлення» і «списати оплату» з’являються серіалізація, мережа, таймаут, повтор і ризик, що відповідь так і не дійде. Саме тому проєктування меж важливіше за вибір фреймворка.
Типовий життєвий цикл виглядає так. Клієнт звертається до шлюзу API. Шлюз автентифікує запит, маршрутизує його до потрібної служби, інколи агрегує відповіді кількох сервісів. Служба обробляє команду, записує дані у власну базу й, за потреби, публікує подію в брокер — Kafka, RabbitMQ чи інший. Інші сервіси реагують на подію вже у своєму темпі. Транзакції між базами замінюють саги: ланцюжок локальних кроків із компенсувальними діями, якщо якийсь крок не вдався.
Дані навмисно не звалюють в одну схему. Патерн «база на сервіс» захищає незалежність: каталог не читає таблиці оплати напряму, інакше зміна колонки в одній команді ламає реліз іншої. З цього випливає остаточна узгодженість. Замовлення може кілька секунд існувати в статусі «очікує оплату», поки сервіс платежів підтвердить списання. Для вітрини інтернет-магазину це прийнятно. Для банківського проведення в ту ж мілісекунду — уже ні.
Мікросервіс «маленький» не за кількістю рядків коду, а за шириною відповідальності: одна бізнес-здатність, один обмежений контекст, один привід змінюватися.
Навколо цього ядра наростає інфраструктура, без якої розподілена система швидко стає хаосом. Service discovery знаходить живі екземпляри. Балансувальник розкидає навантаження. Вимикач (circuit breaker) припиняє слати запити до служби, яка вже не відповідає, щоб каскад відмов не звалив усе. Трасування, метрики й структуровані логи збирають картину запиту, який пройшов через п’ять процесів. Без цієї спостережуваності дебаг перетворюється на ворожіння.
Для початківця корисна аналогія з рестораном. Кухня, каса, доставка й склад — окремі «служби». Офіціант не лізе в холодильник бухгалтера. Якщо каса зависла, кухня все одно готує вже прийняті замовлення. Для досвідченого інженера та сама картина читається інакше: окремі процеси, окремі схеми даних, контракти, ретраї, ідемпотентність і бюджет затримки на кожному хопі.
Від майстерні під Венецією до хмарних кластерів
Саме слово закріпилося не в маркетинговому відділі хмарного гіганта, а на зустрічі архітекторів поблизу Венеції в травні 2011 року. У травні 2012-го та сама група обрала назву «microservices». Джеймс Льюїс тоді вже показував «мікросервіси — Java на Unix-шлях», Фред Джордж говорив про дрібні служби з мінімумом церемоній, а Адріан Коккрофт у Netflix описував підхід як дрібнозернисту SOA. Канонічне формулювання з’явилося в статті Льюїса й Мартіна Фаулера на martinfowler.com у березні 2014-го: один застосунок як набір малих служб, кожна у власному процесі, зі спілкуванням через легкі протоколи й майже без централізованого диригента.
Коріння глибше за назву. Філософія Unix — «роби одну річ і роби її добре» — прямо читається в ідеї вузької служби. Закон Конвея 1968 року пояснює організаційний бік: система копіює структуру комунікацій компанії. Amazon перетворив це на практику «two-pizza teams» і принцип «you build it, you run it»: команда, яку можна нагодувати двома піцами, володіє сервісом від коду до нічного чергування. Netflix пішов далі в інженерію відмов: Chaos Monkey навмисно вбивав інстанси в проді, бібліотека Hystrix ізолювала каскадні падіння. Сотні служб, мільярди викликів API на добу — не рекламний слоган, а наслідок того, що моноліт DVD-епохи фізично не витримував темпу змін.
До 2026 року мікросервіси перестали бути модною ставкою «на виріст» і стали однією з кількох робочих норм. За звітом Cloud Native Computing Foundation спільно зі SlashData (State of Cloud Native Development, листопад 2025) мікросервісний підхід використовують 46% бекенд-розробників, шлюзи API — 50%. Хмарно-нативних розробників у світі налічують близько 15,6 млн. Водночас ринок охолов від лозунга «все в мікросервіси». Модульний моноліт, event-driven зв’язка й вибіркове винесення «гарячих» контурів частіше виграють у команд до кількох десятків інженерів, ніж повне розрізання системи на старті.
Моноліт, SOA і мікросервіс: що насправді відрізняється
Суперечка «моноліт проти мікросервісів» часто підміняє точніше питання: де проходить межа розгортання. Моноліт — одна збірка, один процес, одна база. Модульний моноліт зберігає цю межу, але жорстко ріже код на модулі з чіткими API всередині процесу. SOA історично будувала корпоративну шину з важкими контрактами й центральним оркестратором. Мікросервіс дрібніший, автономніший і навмисно уникає «розумної труби» на кшталт ESB: логіка сидить у кінцевих точках, канал лише доставляє повідомлення.
| Ознака | Моноліт | Модульний моноліт | Мікросервіс |
|---|---|---|---|
| Межа розгортання | Весь застосунок | Весь застосунок, модулі всередині | Окрема служба |
| Дані | Спільна база | Часто спільна база, ізоляція схемами | База на сервіс, поліглот-зберігання |
| Масштабування | Лише цілком | Цілком, з перспективою винести модуль | Точково, за навантаженням служби |
| Відмова | Падає все | Падає процес, модуль ізольований логічно | Деградує функція, решта живе |
| Складність | У коді | У межах модулів | У мережі, даних і експлуатації |
| Команда | Спільний реліз | Команди за модулями, один пайплайн | Команда володіє сервісом «від і до» |
Джерела порівняльних критеріїв: стаття James Lewis і Martin Fowler на martinfowler.com (2014); звіт CNCF / SlashData State of Cloud Native Development, листопад 2025.
SOA інколи плутають із мікросервісами через спільне слово «сервіс». Різниця практична. Класична SOA орієнтована на інтеграцію багатьох корпоративних систем через важкі протоколи й центральну шину. Мікросервісна архітектура будує один продукт як набір дрібних деплой-одиниць. Там, де SOA ставила оркестратор, мікросервіси частіше обирають хореографію: служби танцюють за подіями, а не чекають команди диригента.
Контейнери й Kubernetes не є визначенням мікросервісу. Docker пакує процес. Оркестратор стежить, щоб екземплярів було стільки, скільки треба, і піднімає нові після падіння. Можна тримати кілька служб на віртуальних машинах без кластера. Можна загорнути моноліт у контейнер і нічого не виграти в незалежності. Інфраструктура підсилює стиль, але не замінює межі відповідальності.
Поширені помилки, які перетворюють сервіси на розподілений моноліт
Найдорожчий результат невдалого розрізання — не «занадто багато сервісів», а розподілений моноліт: деплоїти треба всі одразу, бази спільні, виклики синхронні ланцюжком із восьми хопів, і жодна команда не може випустити зміну самостійно. Нижче — типові кроки, які туди ведуть.
- Різати за шарами, а не за бізнесом. Окремий «сервіс бази», окремий «сервіс UI», окремий «сервіс бізнес-логіки» відтворюють тришарову схему моноліту в мережі. Межа має проходити по здатності: «каталог», «кошик», «оплата», «доставка». Інакше будь-яка фіча чіпає три репозиторії й три пайплайни.
- Залишити одну спільну базу «на час переходу». Тимчасове часто стає постійним. Як тільки два сервіси пишуть у ті самі таблиці, незалежне розгортання зникає: міграція схеми блокує всіх. Краще дублювати потрібні дані через події, ніж ділитися рядками.
- Зробити мікросервіс на кожен ендпоінт. /products і /products/{id}/related як дві служби — це не архітектура, а осколки. Служба має закривати сценарій користувача, а не рядок у специфікації OpenAPI.
- Синхронний ланцюжок без бюджету затримки. Якщо оформлення замовлення чекає каталог, знижки, склад, антифрод і оплату послідовно, p99 латентність складається, а падіння будь-якого кільця зупиняє checkout. Частину кроків виносять у події, частину — за вимикач із деградованою відповіддю.
- Розподілені транзакції «як у моноліті». Двофазний коміт між службами крихкий і повільний. Сага, ідемпотентні обробники й явні компенсації («скасувати резерв», «повернути кошти») складніші концептуально, але відповідають природі мережі.
- Ігнорувати організацію. П’ять сервісів на двох розробників означають, що ночі підуть на пайплайни, а не на продукт. Мікросервіс окупається, коли команда може нести його повний цикл. Інакше модульний моноліт дешевший і чесніший.
Окремий міф: «мікросервіси самі по собі швидші». Мережевий виклик завжди повільніший за виклик функції. Виграш з’являється в іншому місці — у паралельній роботі команд, у точковому масштабуванні «гарячого» сервісу, у можливості відкотити одну службу, не чіпаючи решту. Якщо проблема зараз у повільному SQL-запиті, розрізання її не вилікує.
Кейс: інтернет-магазин, у якому «кошик» жив окремо від «оплати»
У нашій практиці ми стикалися з таким випадком, коли команда з дев’яти людей розрізала моноліт інтернет-магазину на 22 служби ще до першої тисячі замовлень на день. Каталог, кошик, промокоди, склад, доставка, оплата, листи, «рекомендації», адмінка — кожне з цих слів стало окремим репозиторієм. Реліз фічі «безкоштовна доставка від 1500 грн» зайняв три тижні узгоджень контрактів. Локально магазин уже не запускався: потрібен був docker-compose на 22 контейнери й тестові ключі платіжки.
Ми провели тест на 100 користувачах і виявили, що оформлення замовлення, яке в моноліті вкладалося в 180–220 мс на p95, після розрізання стрибнуло понад 900 мс. Не через «поганий код», а через чотири послідовні HTTP-виклики на критичному шляху, кожен із яких відкривав TLS і ходив у свою базу. Склад відповідав 99,2% часу — і цього вистачало, щоб раз на кілька хвилин зривати checkout.
Відкотили межі, а не «ідею мікросервісів». Залишили три контури: каталог (читання, важке кешування), checkout (кошик + промокод + створення замовлення в одній службі) і платежі (окрема служба з вимогами PCI й власним циклом релізів). Рекомендації повернули модулем у каталог. Листи пішли в чергу, а не в синхронний виклик. Через шість тижнів p95 повернувся до 250–300 мс, а фічі знову виходили щотижня. Платіжний сервіс справді виграв від ізоляції: його можна було оновлювати в п’ятницю ввечері, не чіпаючи вітрину.
Мораль кейсу суха. Мікросервіс виправдовує себе там, де межа збігається з реальною віссю змін і ризику. Платіжка змінюється з іншої причини, ніж картка товару, і падати їм треба по-різному. Промокод і кошик змінюються разом — тож різати їх зарано.
Чек-лист: чи варто дробити систему саме зараз
Перед тим як заводити новий репозиторій, пройдіться пунктами чесно, без бажання «бути сучасними». Якщо ствердних відповідей менше ніж п’ять, модульний моноліт майже напевно дасть той самий організаційний ефект дешевше.
- Є щонайменше дві команди, які регулярно блокують одна одну спільним релізом.
- Пікове навантаження нерівномірне: масштабувати треба одну здатність (пошук, стрім, оплату), а не весь застосунок.
- Відмова частини функцій допустима для бізнесу: вітрина може жити без рекомендацій, але не без кошика.
- Обмежені контексти вже видно в коді й у розмовах домену, а не лише на слайді.
- Є автоматизований пайплайн, контейнеризація, централізовані логи, метрики й алерти. Без цього новий сервіс — це новий нічний дзвінок.
- Команда готова володіти експлуатацією: он-кол, дашборди, бюджет помилок, політику повторів.
- Є зрозуміла стратегія даних: хто джерело правди, як роз’їжджаються копії, що робити з компенсаціями.
- Мережевий бюджет на критичний сценарій пораховано. Якщо на шляху користувача більше двох-трьох синхронних хопів — межу проведено погано.
- Безпека продумана на межі: автентифікація на шлюзі, авторизація в службі, секрети не в образах, трафік між сервісами не «відкритий, бо всередині VPC».
- Є план відкоту однієї служби й план спостереження за сагою, а не лише за HTTP 200 на шлюзі.
Початківцю цей список здається бюрократією. На практиці він відсікає ситуацію, коли Docker є, а контракту даних немає. Досвідченому архітекторові він нагадує інше: мікросервіс — це податок на складність, який сплачують інфраструктурою, щоб купити автономію команд.
Коли система вже «сиплеться»: тривожні сигнали
За моїм досвідом супроводу мікросервісного контуру протягом місяця після розрізання моноліту перші симптоми рідко виглядають як «сервіс упав». Частіше продукт «просто тупить», а дашборд зеленого кольору, бо кожна служба окремо жива.
Перший сигнал — зростання p95/p99 без зростання CPU. Це майже завжди черги на мережі, ретраї, холодні з’єднання або синхронний ланцюжок. Дивіться трейс одного користувацького сценарію, а не середнє по кластеру. Другий — роз’їзд даних: замовлення є, оплати немає, або навпаки. Шукайте обрив саги, неідемпотентний обробник, який відпрацював двічі, і відсутність outbox-патерну (запис у базу й публікація події в одній локальній транзакції).
Третій сигнал — «реліз однієї служби ламає іншу». Контракт змінили без версії, поле прибрали, споживач не толерантний до зайвих атрибутів. Тут рятують consumer-driven contracts і правило читача, який ігнорує невідоме. Четвертий — вибух вартості інфраструктури: десятки малих інстансів простоюють, але кожен тримає власний кластер бази, власний пул з’єднань і власний дашборд. Точкове об’єднання «холодних» служб назад у модуль — нормальна інженерна дія, а не поразка.
Якщо для локального запуску продукту потрібен оркестр із двох десятків контейнерів, а нова людина в команді тиждень ставить середовище — межі проведені дрібніше, ніж команда здатна нести.
Каскадні відмови лікуються не «ще одним репліками». Вимикач, таймаут коротший за терпіння користувача, кеш на читаннях, черга на записах, деградований режим («показати наявність із кешу, якщо склад не відповідає») — це і є проєктування з розрахунком на відмову, про яке писали автори класичного визначення ще 2014-го.
Коли варто кликати архітектора, а коли вистачить команди
Самій команді варто залишатися в модульному моноліті, якщо продукт один, людей менше десятка, реліз іде щотижня й головний біль — у доменній логіці, а не в черзі деплоїв. Чіткі модулі, заборона на імпорт «через стіну», окремі схеми в одній базі — цього часто вистачає на роки. Винести згодом платіжку чи нотифікації як перший справжній мікросервіс простіше, ніж склеювати двадцять осколків.
Архітектора або платформенну команду варто кликати, коли з’являється хоча б одна з умов: кілька продуктових команд на спільній системі; вимоги ізоляції (PCI, персональні дані, окремий контур відмови); потреба в поліглоті (Python для ML-скорингу поруч із JVM-ядром); або вже є розподілені гонки, які не лікуються індексом у Postgres. Фахівець тут потрібен не щоб «намалювати сервіси», а щоб провести bounded context, бюджет затримки, модель даних і мінімальний набір платформенних сервісів: шлюз, ідентичність, телеметрія, CI/CD, секрети.
Окремий випадок — регульовані галузі й публічний сектор в Україні, де контури персональних даних, резервного копіювання й аудиту жорсткіші за бажання «мікросервісити все». Там частіше виграє гібрид: ядро з модулів плюс кілька ізольованих служб на периметрі. Це не відсталість, а відповідність вартості ризику.
Питання, які з’являються після першого релізу
Чим мікросервіс відрізняється від «просто API»?
API — це спосіб розмови. Мікросервіс — спосіб життя компонента: власний процес, власне розгортання, власні дані, власна відповідальність за відмову. Моноліт теж може віддавати REST. Поки служба не може вийти в прод окремо від сусідів, це модуль з HTTP-фасадом, а не мікросервіс.
Скільки служб — це вже забагато?
Немає магічного числа. Орієнтир практичний: команда з 6–8 людей комфортно несе дві-чотири служби, не двадцять. Якщо кількість сервісів росте швидше за кількість команд, ви ріжете технічні шари або ендпоінти, а не домен. Об’єднання «тихих» служб назад — законна еволюція, її все частіше фіксують у галузевих оглядах середини 2020-х.
Чи обов’язковий Kubernetes?
Ні. Кластер окупається, коли екземплярів багато, деплої часті, потрібні автоскейл, самовідновлення й однакова платформа для кількох команд. Для трьох служб на одному хмарному акаунті вистачить керованих контейнерів або навіть кількох віртуальних машин із нормальним пайплайном. Оркестратор не створює межі — він їх експлуатує.
Як винести перший сервіс із моноліту, не зупиняючи продукт?
Працює стратегія «ліани» (strangler fig): новий контур пишеться поряд, шлюз поступово переводить на нього частину трафіку, старий код відмирає. Починають зі здатності, яка має власні дані й власний ритм змін — часто це нотифікації, пошук, генерація файлів, іноді оплата. Антикорупційний шар на межі зі старим ядром береже новий сервіс від чужої моделі даних.
Чи можна писати служби різними мовами?
Так, і це одна з обіцянок стилю. Робіть це там, де мова дає реальний виграш: Go для навантаженого проксі, Python для офлайн-скорингу, JVM для складної доменної логіки. Кожна нова мова — це ще один спосіб збирати, логувати, профілювати й наймати людей. Поліглот без потреби дорожчий за «нудну» однаковість.
Мікросервіс виправдовує себе не красивою діаграмою, а простим тестом: чи може одна команда змінити, випустити й відкотити свою службу в робочий день, не збираючи нараду з половиною компанії.
Той самий тест працює в інший бік. Якщо автономія не потрібна, якщо дані все одно спільні, якщо людей мало — незалежна цеглина перетворюється на ще одну точку відмови. Тоді чесна модульність усередині одного процесу дає більшу швидкість, ніж мережа з десятків дрібних служб. Архітектура має служити темпу змін продукту, а не навпаки: служби з’являються там, де системі справді стає тісно, і зникають там, де тісноти вже немає.




