Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

19 вересня у Москві відбувся перший тематичний мітап HUG (Highload++ User Group), присвячений мікросервісам. На ньому прозвучала доповідь «Експлуатація мікросервісів: розмір має значення, навіть якщо у вас Kubernetes», де ми поділилися великим досвідом компанії «Флант» в галузі експлуатації проектів з мікросервісною архітектурою. Насамперед він буде корисним усім розробникам, які замислюються про застосування цього підходу у своєму теперішньому чи майбутньому проекті.

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

представляємо відео з доповіддю (50 хвилин, набагато інформативніше статті), а також основне вичавлення з нього в текстовому вигляді.

NB: Відео та презентація доступні також наприкінці цієї публікації.

Запровадження

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

Почну з такого графіка, автором якого (2015 року) став Martin Fowler:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

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

Доповню цей графік для використання Kubernetes:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

Чому програмі з мікросервісами стало краще? Тому що така архітектура висуває серйозні вимоги до архітектури, які, у свою чергу, чудово закриваються можливостями Kubernetes. З іншого боку, частина цієї функціональності буде корисна і для моноліту, особливо тому, що типовий на сьогоднішній день моноліт — це не зовсім моноліт (подробиці будуть далі в доповіді).

Як видно, підсумковий графік (коли і монолітне, і мікросервісне застосування в інфраструктурі з Kubernetes) не дуже відрізняється від початкового. Далі йтиметься про програми, що експлуатуються з використанням Kubernetes.

Корисна та шкідлива мікросервісність

І тут головна думка:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

Що ж таке нормальна Мікросервісна архітектура? Вона має приносити вам реальну користь, збільшуючи ефективність роботи. Якщо повернутися до графіка, то ось вона:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

Якщо називати її корисний, то з іншого боку графіка буде шкідлива мікросервісність (заважає роботі):

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

Повертаючись до «головної думки»: чи варто взагалі довіряти моєму досвіду? З початку цього року я подивився 85 проектів. Не всі вони були мікросервісними (такої архітектури мали приблизно від третини до половини з них), але це все одно велика кількість. Нам (компанії «Флант») як аутсорсерам вдається бачити широке розмаїття додатків, що розробляються як у маленьких компаніях (з 5 розробниками), так і у великих (500 розробників). Додатковим плюсом є те, що ми бачимо, як ці програми живуть і розвиваються протягом багатьох років.

Навіщо мікросервіси?

На питання про користь мікросервісів є дуже конкретна відповідь у вже згаданого Martin Fowler:

  1. точні межі модульності;
  2. незалежний деплой;
  3. свобода вибору технологій.

Я багато розмовляв з архітекторами та розробниками програмного забезпечення та запитував, навіщо їм мікросервіси. І склав свій список їхніх очікувань. Ось що вийшло:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

Якщо описати «у відчуттях» деякі з пунктів, то:

  • точні межі модулів: ось у нас є страшний моноліт, а тепер все буде акуратно розкладено по Git-репозиторіям, у яких все «по поличках», не перемішане тепле з м'яким;
  • незалежність деплою: ми зможемо викочувати послуги незалежно, щоб розробка йшла швидше (паралельно публікувати нові фічі);
  • незалежність розробки: ми можемо віддати цей мікросервіс тій команді/розробнику, а той інший, завдяки чому зможемо швидше розробляти;
  • бобільша надійність: якщо трапиться часткова деградація (впаде один мікросервіс з 20), то перестане працювати лише одна кнопка, а система загалом продовжить функціонувати.

Типова (шкідлива) мікросервісна архітектура

Щоб пояснити, чому насправді все не так, як ми очікуємо, я представлю збірний образ мікросервісної архітектури, заснований на досвіді з різних проектів.

Прикладом буде служити абстрактний інтернет-магазин, який збирається конкурувати з Amazon або хоча б OZON. Його мікросервісна архітектура виглядає так:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

За сукупністю причин, ці мікросервіси написані на різних платформах:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

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

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

Які її наслідки?

У Fowler'а і на цей рахунок є стаття - про «розплату» за використання мікросервісів:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

А ми подивимося, чи справдилися наші очікування.

Точні межі модулів…

Але скільки мікросервісів нам насправді потрібно поправитищоб викотити зміну? Чи можемо взагалі розібратися, як все працює, без розподіленого трасувальника (адже будь-який запит обробляється половиною мікросервісів)?

Існує патернвелика грудка бруду», а тут і зовсім вийшла розподілена грудка бруду. На підтвердження тому — ось зразкова ілюстрація того, як ходять запити:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

Незалежність деплою.

Технічно її досягнуто: ми можемо перекотити кожен мікросервіс окремо. Але на практиці потрібно враховувати, що завжди викочується безліч мікросервісів, причому нам потрібно враховувати порядок їх викочування. По-доброму нам взагалі потрібно в окремому контурі тестувати, чи правильно ми викочуємо реліз.

Свобода вибору технології…

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

Незалежність розробки.

Як зробити тестовий контур для всієї програми (з такої множини компонентів)? Адже ще треба його підтримувати в актуальному вигляді. Все це призводить до того, що реальна кількість тестових контурів, яке ми в принципі можемо містити, виявляється мінімальним.

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

Роздільна масштабування.

Так, але воно обмежене в галузі використовуваних СУБД. У наведеному прикладі архітектури не буде проблем у Cassandra, але будуть у MySQL та PostgreSQL.

Бобільша надійність…

Мало того, що насправді виведення з ладу одного мікросервісу найчастіше ламає коректне функціонування всієї системи, то є ще й нова проблема: зробити стійким до відмови кожен мікросервіс дуже складно. Тому що в мікросервісах використовуються різні технології (memcache, Redis і т.п.), для кожного потрібно все продумати та реалізувати, що, звичайно, можливо, але потребує величезних ресурсів.

Вимірність навантаження.

Із цим справді все добре.

«Легкість» мікросервісів.

У нас не лише з'явилися величезні мережеві накладні витрати (збільшуються запити на DNS і т.п.), але й через безліч підзапитів ми почали реплікувати дані (Зберігати кеші), що призвело до значного обсягу сховищ.

І ось який підсумок відповідності нашим очікуванням:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

Але це ще не все!

Тому що:

  • Швидше за все нам знадобиться шина повідомлень.
  • Як зробити консистентний бекап на потрібний момент часу? Єдиний реальний варіант - вимкнути трафік для цього. Але як це зробити на production?
  • Якщо мова йде про підтримку кількох регіонів, то організувати стійкість у кожному їх — дуже трудомістка завдання.
  • Виникає проблема внесення централізованих змін. Наприклад, якщо нам потрібно оновити версію PHP, потрібно буде зробити коміт у кожен репозиторій (а їх — десятки).
  • Зростання операційної складності навскідку виходить експоненційним.

Що з цим робити?

Починайте з монолітної програми. Досвід Fowler'а каже про те, що практично всі успішні мікросервісні програми починалися з моноліту, який став занадто великим, після чого і був розбитий. У той самий час майже всі системи, побудовані як мікросервісні від початку, рано чи пізно відчували серйозні проблеми.

Ще одна цінна думка — щоб проект із мікросервісною архітектурою був успішним, ви маєте дуже добре знати і предметну область, і як робити мікросервіси. А найкращий спосіб дізнатися про предметну область — зробити моноліт.

Але що робити, якщо ми вже опинилися у такій ситуації?

Перший крок до вирішення будь-якої проблеми — погодитися з нею та зрозуміти, що це проблема, що ми більше не хочемо страждати.

Якщо у випадку моноліту, що розрісся (коли в нас закінчилася можливість докуповувати для нього ресурси), ми його розрізаємо, то в даному випадку виходить зворотна історія: коли надмірна мікросервісність вже не допомагає, а заважає. відрізайте зайве та укрупнюйте!

Наприклад, для розглянутого вище збірного образу…

Позбудьтеся самих сумнівних мікросервісів:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

Об'єднайте всі мікросервіси, що відповідають за генерацію фронтенду:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

… в один мікросервіс, написаний однією (сучасною та нормальною, як ви самі вважаєте) мовою/фреймворком:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

У нього буде один ORM (одна СУБД) і спочатку пара додатків:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

… а взагалі туди можна перенести набагато більше, отримавши такий результат:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

Причому в Kubernetes ми все це запускаємо окремими екземплярами, а значить, ми все ще можемо вимірювати навантаження і окремо масштабувати їх.

Резюмуючи

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

У слові "мікросервіси" частина "мікро" є зайвою. Вони «мікро» лише тому, що менше величезного моноліту. Але не треба думати про них як про щось маленьке.

І для фінальної думки повернемося до первісного графіка:

Мікросервіси: розмір має значення навіть якщо у вас Kubernetes

Написана до нього примітка (праворуч нагорі) зводиться до того, що навички команди, яка робить ваш проект, завжди первинні — саме вони відіграють ключову роль у вашому виборі між мікросервісами та монолітом. Якщо у команди не вистачає умінь, але вона починає робити мікросервіси, історія точно буде фатальною.

Відео та слайди

Відео з виступу (~50 хвилин; на жаль, воно не передає численні емоції відвідувачів, що багато в чому визначало настрій доповіді, але як є):

Презентація доповіді:

PS

Інші доповіді у нашому блозі:

Ймовірно, вас також зацікавлять такі публікації:

Джерело: habr.com

Додати коментар або відгук