Мікрасэрвісы: памер мае значэнне, нават калі ў вас Kubernetes
19 верасня ў Маскве адбыўся першы тэматычны мітап HUG (Highload++ User Group), які быў прысвечаны мікрасэрвісам. На ім прагучаў даклад "Эксплуатацыя мікрасэрвісаў: памер мае значэнне, нават калі ў вас Kubernetes", у якім мы падзяліліся шырокім вопытам кампаніі "Флант" у галіне эксплуатацыі праектаў з мікрасэрвіснай архітэктурай. У першую чаргу ён будзе карысны ўсім распрацоўнікам, якія задумваюцца аб ужыванні гэтага падыходу ў сваім сучаснасці або будучыні праекце.
Прадстаўляем відэа з дакладам (50 хвілін, значна інфарматыўныя за артыкул), а таксама асноўны выціск з яго ў тэкставым выглядзе.
NB: Відэа і прэзентацыя даступныя таксама напрыканцы гэтай публікацыі.
Увядзенне
Звычайна добрая гісторыя мае завязку, асноўны сюжэт і развязку. Гэты даклад больш падобны на завязку, прычым трагічную. Таксама важна адзначыць, што ў ім прадстаўлены погляд на мікрасэрвісы з боку эксплуатацыі.
Пачну з такога графіка, аўтарам якога (у 2015 годзе) стаў Martin Fowler:
На ім відаць, як у выпадку маналітнага дадатку, які дасягнуў пэўнай велічыні, пачынае падаць прадуктыўнасць працы. Мікрасэрвісы адрозніваюцца тым, што першапачатковая прадуктыўнасць з імі ніжэй, аднак па меры росту складанасці дэградацыя эфектыўнасці для іх не так прыкметная.
Дапоўню гэты графік для выпадку выкарыстання Kubernetes:
Чаму дадаткам з мікрасэрвісамі стала лепш? Таму што такая архітэктура высоўвае сур'ёзныя патрабаванні да архітэктуры, якія ў сваю чаргу выдатна зачыняюцца магчымасцямі Kubernetes. З іншага боку, частка гэтай функцыянальнасці будзе карысная і для маналіта, асабліва па той прычыне, што тыповы на сённяшні дзень маналіт - гэта не зусім маналіт (падрабязнасці будуць далей у дакладзе).
Як відаць, выніковы графік (калі і маналітнае, і мікрасэрвіснае прыкладанні ў інфраструктуры з Kubernetes) не вельмі-то адрозніваецца ад першапачатковага. Далей гаворка будзе ісці аб прыкладаннях, якія эксплуатуюцца з выкарыстаннем Kubernetes.
Карысная і шкодная мікрасэрвіснасць
І тут галоўная думка:
Што ж такое нармальная мікрасэрвісная архітэктура? Яна павінна прыносіць вам рэальную карысць, павялічваючы эфектыўнасць працы. Калі вярнуцца да графіка, то вось яна:
Калі называць яе карысны, то на другім баку графіка будзе шкодная мікрасэрвіснасць (перашкаджае працы):
Вяртаючыся да «галоўнай думкі»: ці варта ўвогуле давяраць майму вопыту? З пачатку гэтага года я паглядзеў 85 праектаў. Не ўсе яны былі мікрасэрвісныя (такой архітэктурай валодалі прыкладна ад траціны да паловы з іх), але гэта ўсё роўна вялікі лік. Нам (кампаніі «Флант») як аўтсорсерам атрымоўваецца бачыць шырокую разнастайнасць прыкладанняў, якія распрацоўваюцца як у маленькіх кампаніях (з 5 распрацоўшчыкамі), так і ў буйных (~500 распрацоўшчыкаў). Дадатковым плюсам з'яўляецца тое, што мы бачым, як гэтыя прыкладанні жывуць і развіваюцца на працягу многіх гадоў.
Навошта мікрасэрвісы?
На пытанне аб карысці мікрасэрвісаў ёсць вельмі канкрэтны адказ ва ўжо згаданага Martin Fowler:
выразныя межы модульнасці;
незалежны дэплой;
свабода выбару тэхналогій.
Я шмат размаўляў з архітэктарамі і распрацоўшчыкамі праграмнага забеспячэння і пытаўся, навошта ім мікрасэрвісы. І склаў свой спіс іх чаканняў. Вось што атрымалася:
Калі апісаць "у адчуваннях" некаторыя з пунктаў, то:
выразныя межы модуляў: вось у нас ёсць страшны маналіт, а зараз усё будзе акуратна раскладзена па Git-рэпазітарах, у якіх усё «па палічках», не перамяшана цёплае з мяккім;
незалежнасць дэплою: мы зможам выкочваць сэрвісы незалежна, каб распрацоўка ішла хутчэй (паралельна публікаваць новыя фічы);
незалежнасць распрацоўкі: мы можам аддаць гэты мікрасэрвіс той камандзе/распрацоўніку, а той - іншы, дзякуючы чаму зможам хутчэй распрацоўваць;
бовялікая надзейнасць: калі здарыцца частковая дэградацыя (упадзе адзін мікрасэрвіс з 20), то перастане працаваць толькі адна кнопка, а сістэма ў цэлым працягне функцыянаваць.
Тыпавая (шкодная) мікрасэрвісная архітэктура
Каб растлумачыць, чаму ў рэальнасці ўсё не так, як мы чакаем, я прадстаўлю зборны выява мікрасэрвіснай архітэктуры, заснаваны на досведзе з мноства розных праектаў.
Прыкладам будзе служыць абстрактны інтэрнэт-крама, які збіраецца канкураваць з Amazon ці хаця б OZON. Яго мікрасэрвісная архітэктура выглядае так:
Па сукупнасці прычын, гэтыя мікрасэрвісы напісаны на розных платформах:
Паколькі ў кожнага мікрасэрвісу павінна быць аўтаномнасць, многія з іх маюць патрэбу ў сваёй базе даных і кэшы. Фінальная архітэктура атрымліваецца наступнай:
Якія яе наступствы?
У Fowler'а і на гэты конт ёсць артыкул - аб «расплаце» за выкарыстанне мікрасэрвісаў:
А мы паглядзім, ці спраўдзіліся нашыя чаканні.
Выразныя межы модуляў…
Але колькі мікрасэрвісаў нам у рэчаіснасці трэба паправіць, Каб выкаціць змена? Ці можам мы наогул разабрацца, як усё працуе, без размеркаванага трасіроўшчыка (бо любы запыт апрацоўваецца паловай мікрасэрвісаў)?
Існуе патэрнвялікі камяк бруду», а тут і зусім атрымаўся размеркаваны камяк бруду. У пацверджанне таму - вось прыкладная ілюстрацыя таго, як ходзяць запыты:
Незалежнасць дэплою…
Тэхнічна яна дасягнута: мы можам перакаціць кожны мікрасэрвіс асобна. Але на практыцы трэба ўлічваць, што заўсёды выкочваецца мноства мікрасэрвісаў, прычым нам трэба ўлічваць парадак іх выкату. Па-добраму нам наогул трэба ў асобным контуры тэсціраваць, ці ў правільным парадку мы выкочваем рэліз.
Воля выбару тэхналогіі…
Яна ёсць. Толькі варта памятаць, што часта свабода мяжуе з бязмежжам. Вельмі важна тут не выбіраць тэхналогіі толькі для таго, каб "пагуляць" з імі.
Незалежнасць распрацоўкі…
Як зрабіць тэставы контур для ўсяго прыкладання (з такога мноства кампанентаў)? А яшчэ трэба яго падтрымліваць у актуальным выглядзе. Усё гэта прыводзіць да таго, што рэальная колькасць тэставых контураў, якое мы ў прынцыпе можам змяшчаць, аказваецца мінімальным.
А разгарнуць усё гэта лакальна?.. Атрымліваецца, што часцяком распрацоўнік робіць сваю працу незалежна, але "наўздагад", таму што змушаны чакаць, калі вызваліцца контур для тэставання.
Паасобнае маштабаванне…
Так, але яно абмежавана ў вобласці СУБД, якія выкарыстоўваюцца. У прыведзеным прыкладзе архітэктуры не будзе праблем у Cassandra, але будуць у MySQL і PostgreSQL.
Бовялікая надзейнасць…
Мала таго, што ў рэчаіснасці выснова з ладу аднаго мікрасэрвісу часцяком ламае карэктнае функцыянаванне ўсёй сістэмы, так ёсць яшчэ і новая праблема: зрабіць адмоваўстойлівасцю кожны мікрасэрвіс вельмі складана. Таму што ў мікрасэрвісах выкарыстоўваюцца розныя тэхналогіі (memcache, Redis і да т.п.), для кожнага трэба ўсё прадумаць і рэалізаваць, што, вядома, магчыма, але патрабуе вялізных рэсурсаў.
Вымернасць нагрузкі…
З гэтым сапраўды ўсё добра.
"Лёгкасць" мікрасэрвісаў…
У нас не толькі з'явіліся вялізныя сеткавыя накладныя выдаткі (Прамножваюцца запыты на DNS і да т.п.), але і з-за мноства подзапросов мы пачалі рэпліцыраваць дадзеныя (захоўваць кэшы), што прывяло да значнага аб'ёму сховішчаў.
І вось які вынік адпаведнасці нашым чаканням:
Але і гэта яшчэ не ўсё!
Таму што:
Хутчэй за ўсё нам спатрэбіцца шына паведамленняў.
Як зрабіць кансістэнтны бэкап на патрэбны момант часу? Адзіны рэальны варыянт - выключыць трафік для гэтага. Але як гэта зрабіць на production?
Калі ідзе гаворка аб падтрымцы некалькіх рэгіёнаў, то арганізаваць устойлівасць у кожным з іх - вельмі працаёмкая задача.
З'яўляецца праблема ўнясення цэнтралізаваных змен. Напрыклад, калі нам трэба абнавіць версію PHP, тое запатрабуецца зрабіць коміт у кожны рэпазітар (а іх - дзясяткі).
Рост аперацыйнай складанасці наўскідку атрымліваецца экспанентным.
Што з усім гэтым рабіць?
Пачынайце з маналітнага прыкладання. Вопыт Fowler'а кажа пра тое, што практычна ўсе паспяховыя мікрасэрвісныя прыкладанні пачыналіся з маналіта, які стаў занадта вялікім, пасля чаго і быў разбіты. У той жа самы час практычна ўсе сістэмы, пабудаваныя як мікрасэрвісныя з самага пачатку, рана ці позна выпрабоўвалі сур'ёзныя праблемы.
Яшчэ адна каштоўная думка - каб праект з мікрасэрвіснай архітэктурай быў паспяховым, вы павінны вельмі добрае ведаць і прадметную вобласць, і як рабіць мікрасэрвісы. А лепшы спосаб даведацца прадметную вобласць - зрабіць маналіт.
Але што рабіць, калі мы ўжо аказаліся ў такой сітуацыі?
Першы крок да вырашэння любой праблемы - пагадзіцца з ёй і зразумець, што гэта праблема, што мы больш не хочам пакутаваць.
Калі ў выпадку разрослага маналіта (калі ў нас скончылася магчымасць дакупляць для яго рэсурсы), мы яго разразаем, то ў дадзеным выпадку атрымліваецца адваротная гісторыя: калі празмерная мікрасэрвіснасць ужо не дапамагае, а перашкаджае. адразайце лішняе і ўзбуйняйце!
Напрыклад, для разгледжанай вышэй зборнай выявы…
Пазбаўцеся ад самых сумніўных мікрасэрвісаў:
Аб'яднайце ўсе мікрасэрвісы, якія адказваюць за генерацыю фронтэнда:
… у адзін мікрасэрвіс, напісаны на адной (сучаснай і нармальнай, як вы самі лічыце) мове/фрэймворку:
У яго будзе адзін ORM (адна СКБД) і спачатку пара прыкладанняў:
… а ўвогуле туды можна перанесці значна больш, атрымаўшы такі вынік:
Прычым у Kubernetes мы ўсё гэта запускаем асобнымі асобнікамі, а значыць, што мы ўсё яшчэ можам вымяраць нагрузку і асобна маштабаваць іх.
Рэзюмуючы
Паглядзіце на карціну шырэй. Вельмі часта ўсе гэтыя праблемы з мікрасэрвісамі ўзнікаюць з-за таго, што нехта ўзяў сваю задачу, але хацеў «пагуляць у мікрасэрвісы».
У слове «мікрасэрвісы» частка «мікра» з'яўляецца лішняй. Яны "мікра" толькі па той прычыне, што менш вялізнага маналіта. Але не трэба думаць аб іх як аб нечым маленькім.
І для фінальнай думкі вернемся да першапачатковага графіка:
Напісаная да яго нататка (справа наверсе) зводзіцца да таго, што навыкі каманды, якая робіць ваш праект, заўсёды першасныя - менавіта яны згуляюць ключавую ролю ў вашым выбары паміж мікрасэрвісу і маналітам. Калі ў каманды не хапае ўменняў, але яна пачынае рабіць мікрасэрвісы, гісторыя дакладна будзе фатальнай.
Відэа і слайды
Відэа з выступу (~50 хвілін; нажаль, яно не перадае шматлікія эмоцыі наведвальнікаў, што шмат у чым вызначала настрой дакладу, але ўжо як ёсць):