Інженерна майстерність і карʼєра / крок 06
Головна проблема мікросервісів, яку часто недооцінюють
Про що це відео
Пересторога для всіх, хто планує починати новий проєкт із мікросервісів. Людям вони здаються простішими, «бо маленькі», але проблем більше, ніж видається на перший погляд. Автор починає з фрази Саймона Брауна — «чому ви думаєте, що зможете побудувати мікросервісну архітектуру, якщо не можете побудувати моноліт?» — проходиться по загальновідомих (розв'язуваних) проблемах, а потім доходить до концептуальної, яку вважає недооціненою: у перший день ви ніколи не знаєте домен достатньо добре, щоб правильно нарізати межі сервісів, і, на відміну від моноліту, з мікросервісами виправити невдалий поділ шалено дорого (знання домену, проєктування ПЗ).
Головне
- «Відомі» витрати, які він перелічує спочатку: замість одного бінарника на деплой отримуєте цілий вагон сервісів, яким потрібна платформа оркестрації для збирання/деплою/відкатів; сумісність версій — після відкату сервісу B треба якось гарантувати, що A/B/C і далі стикуються (у моноліті, де весь код їде разом, цієї проблеми немає); окрема база даних у кожного сервісу вбиває транзакційність — для чогось на кшталт бухгалтерської системи, якій потрібна атомарна проводка через кілька сервісів, «розподілені транзакції… просто забудьте»; а виклик іншого модуля в моноліті завжди спрацьовує (він у пам'яті), тоді як мікросервіс може лежати або напівлежати — усе це вимагає патернів обробки й ускладнює програму.
- Він скептичний і до пітчу «правильна технологія під кожну задачу» — по сервісу на кожній із чотирьох мов: чи справді це здешевлює розробку або спрощує підтримку? «Я не впевнений.» Плюс людей, які реально вміють усе це робити, треба ще найняти — на нинішньому ринку це ще одна величезна проблема.
- Ключова ідея — з доповіді Robert C. Martin (посилання під відео): робота архітектора — не ухвалювати рішення, а відкладати їх якомога довше — хороша архітектура максимізує кількість НЕухвалених рішень. Звучить як єресь, але: якість архітектури залежить від того, наскільки добре ви розумієте домен, а розумієте ви його щодня краще, тож рішення, ухвалене пізніше, — краще рішення. Ви свідомо додаєте абстракції (без фанатизму), які дозволяють вирішити потім.
- Мікросервіси — протилежна ставка: вони припускають, що в перший день ви вже знаєте, як порізати систему на шматки, — але ви майже ніколи ще не знаєте домен достатньо добре. Моноліт страждає від тієї самої проблеми неправильних абстракцій, але там є рефакторинг: одна кодова база, одна чи кілька команд, ви легко переносите відповідальності між модулями й класами. З мікросервісами різними мовами, якими володіють різні команди, те саме виправлення — «неймовірно важке».
- Його улюблений механізм деградації: усі роблять кожен мікросервіс гарним і простим, але складність не зникає — вона мігрує на рівень комунікації. Коли межі сервісів виявляються неправильними, команди намагаються полагодити це в міжсервісній комунікації, один сервіс смикає другий, той — третій, додаються зайві сервіси — «виходить каша».
- Підсумок: у ~90% випадків починайте з модульного моноліту (моноліт завжди має бути модульним) — тоді розпиляти його на мікросервіси пізніше, коли ви вже реально розумієте домен і знаєте, навіщо вони вам, значно легше, і зазвичай це працює краще, ніж стартувати з мікросервісів. Як хороший приклад підходу він наводить інженерну статтю Medium про їхню міграцію з моноліту на мікросервіси (посилання під відео).