Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці

Прынцып нявызначанасці Гейзенберга абвяшчае, што нельга адначасова вымераць становішча аб'екта і яго хуткасць. Калі аб'ект рухаецца, то ў яго няма месцазнаходжання. А калі месцазнаходжанне ёсць - значыць у яго няма хуткасці.

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці

Што дакранаецца мікрасэрвісаў на платформе Red Hat OpenShift (і пад кіраваннем Kubernetes), то дзякуючы які адпавядае софту з адчыненым кодам яны могуць адначасова рапартаваць як аб сваёй прадукцыйнасці, так і аб спраўнасці Старога Гейзенберга гэта, вядома, не абвяргае, але затое ўхіляе нявызначанасць пры працы з хмарнымі. (трасіроўку) і маніторынг такіх прыкладанняў, каб трымаць усё пад кантролем.

Вызначаемся з тэрміналогіяй

Пад трасіроўкай (Tracing) мы разумеем лагіраванне сістэмнай актыўнасці. Гучыць даволі агульна, але насамрэч адно з асноўных правілаў тут у тым, каб скідаць дадзеныя трасіроўкі ў адпаведнае сховішча, не клапоцячыся аб іх фарматаванні. А ўся праца па пошуку і аналізе дадзеных ускладаецца на іх спажыўца. У Istio выкарыстоўваецца сістэма трасіроўкі Jaeger, якая рэалізуе мадэль дадзеных OpenTracing.

Трасамі (Traces, і слова "трасы" тут выкарыстоўваецца ў значэнні "сляды", як напрыклад, у балістычнай экспертызе) мы будзем называць дадзеныя, якія цалкам апісваюць праходжанне запыту або адзінку працы, як гаворыцца, "ад і да". Напрыклад, усё, што адбываецца з моманту, калі карыстач цісне кнопку на вэб-старонцы, і да моманту звароту дадзеных, уключаючы ўсе задзейнічаныя пры гэтым мікрасэрвісы. Можна сказаць, што адна траса цалкам апісвае (або мадэлюе) праходжанне запыту туды і назад. У інтэрфейсе Jaeger трасы раскладваецца на складнікі па восі часу, накшталт таго, як ланцуг можна раскласці на асобныя звёны. Толькі замест звёнаў траса складаецца з так званых span'аў.

пралёт - гэта інтэрвал ад пачатку выканання адзінкі працы да яе завяршэння. Працягваючы аналогію, можна сказаць, што кожны span уяўляе сабой асобнае звяно ланцуга. Span можа мець (ці не мець) адзін ці некалькі даччыных span'аў. Як следства, span самага верхняга ўзроўня (root span) будзе мець тую ж агульную працягласць, што і траса, да якой ён ставіцца.

Маніторынг - гэта, уласна, само назіранне за вашай сістэмай - вачыма, праз UI або сродкамі аўтаматызацыі. У аснове маніторынгу ляжаць дадзеныя трасіроўкі. У Istio маніторынг рэалізаваны сродкамі Prometheus і мае адпаведны UI. Prometheus падтрымлівае аўтаматычны маніторынг з выкарыстаннем абвестак Alerts і Alert Managers.

Пакідаем засечкі

Каб трасіроўка стала магчымай, прыкладанне павінна стварыць калекцыю span'аў. Потым іх трэба экспартаваць у Jaeger, каб той у сваю чаргу стварыў візуальнае паданне трасіроўкі. Сярод іншага гэтыя span'ы маркіруюць імя аперацыі, а таксама часовыя пазнакі яе пачатку і завяршэнні. Перадача span'аў выконваецца шляхам пераадрасацыі прызначаных для Jaeger загалоўкаў HTTP-запытаў ад уваходных запытаў да выходных запытаў. У залежнасці ад выкарыстоўванай мовы праграмавання для гэтага можа запатрабавацца невялікая мадыфікацыі зыходнага кода прыкладанняў. Ніжэй прыводзіцца прыклад кода на Java (пры выкарыстанні фрэймворка Spring Boot), які дадае загалоўкі B3 (Zipkin-style) да вашага запыту ў канфігурацыйным класе Spring:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
Пры гэтым выкарыстоўваюцца наступныя налады загалоўкаў:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
Калі вы выкарыстоўваеце Java, то код можна не чапаць, а проста дадаць некалькі радкоў у POM-файл Maven і задаць зменныя асяроддзі. Вось якія радкі трэба дадаць у файл POM.XML, каб укараніць Jaeger Tracer Resolver:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
А адпаведныя зменныя асяроддзі задаюцца ў Dockerfile:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
Усё, зараз усё наладжана, і нашы мікрасэрвісы пачнуць генераваць дадзеныя трасіроўкі.

Глядзім у агульных рысах

У склад Istio уваходзіць прасценькая кантрольная панэль на аснове Grafana. Калі ўсё наладжана і працуе на платформе Red Hat OpenShift PaaS (у нашым прыкладзе Red Hat OpenShift і Kubernetes разгорнутыя на minishift), гэтая панэль запускаецца наступнай камандай:

open "$(minishift openshift service grafana -u)/d/1/istio-dashboard?refresh=5⩝Id=1"

Панэль Grafana дазваляе хутка ацаніць працу сістэмы. Фрагмент гэтай панэлі паказаны на малюнку ніжэй:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
Тут відаць, што мікрасэрвіс customer выклікае мікрасэрвіс preference v1, а той у сваю чаргу выклікае мікрасэрвісы recommendation v1 і v2. На панэлі Grafana ёсць блок Dashboard Row для высокаўзроўневых метрык, такіх як агульная колькасць запытаў (Global Request Volume), доля паспяховых запытаў (success rates), памылкі 4xx. Акрамя таго, там ёсць прадстаўленне Server Mesh з графікамі для кожнага сэрвісу і блок Services Row для прагляду падрабязных звестак па кожным кантэйнеры для кожнага сэрвісу.

Цяпер капнём глыбей

Пры пісьменна наладжанай трасіроўцы Istio, што завецца, прама са скрынкі дазваляе паглыбіцца ў аналіз прадукцыйнасці сістэмы. У Jaeger'аўскім UI можна праглядаць трасіроўкі і бачыць, як далёка і глыбока яны сыходзяць, а таксама візуальна лакалізаваць вузкія месцы ў прадукцыйнасці. Пры выкарыстанні Red Hat OpenShift на платформе minishift запуск Jaeger UI выконваеце наступнай камандай:

minishift openshift service jaeger-query --in-browser

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
Што можна сказаць пра трасіроўку на гэтым скрыне:

  • Яна разбіваецца на 7 span'аў.
  • Агульны час выканання складае 6.99ms.
  • На мікрасэрвіс recommendation, які з'яўляецца апошнім у ланцужку, марнуецца 0.69 ms.

Дыяграмы такога тыпу дазваляюць хутка разабрацца ў сітуацыі, калі з-за нейкага аднаго няважна які працуе сэрвісу пакутуе прадукцыйнасць усёй сістэмы.

А зараз ускладнім задачу і запусцім два асобніка мікрасэрвісу recommendation:v2 камандай oc scale —replicas=2 deployment/recommendation-v2. Вось якія ў нас пасля гэтага будуць pod'ы:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
Калі зараз пераключыцца назад у Jaeger і разгарнуць span для сэрвісу recommendation, мы ўбачым, на які pod маршрутызуюцца запыты. Такім чынам, мы можам лёгка лакалізаваць тормазы на ўзроўні канкрэтнага pod'а. Глядзець пры гэтым трэба на поле node_id:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці

Куды і як усё ходзіць

Зараз пераходзім у інтэрфейс Prometheus і цалкам чакана бачым там, што запыты паміж другой і першай версіямі сэрвісу recommendation дзеляцца ў стаўленні 2:1, строга па колькасці працавальных pod'ов.

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці

Усё толькі пачынаецца

Насамрэч сёння мы, што завецца, толькі злёгку закранулі скарбніцу карыснай інфармацыі аб Jaeger, Grafana і Prometheus. Увогуле-то гэта і была наша мэта - накіраваць вас у патрэбным кірунку і прыадчыніць далягляды Istio.

І падушыце, усё гэта ўжо ўбудавана ў Istio. Пры выкарыстанні вызначаных моў праграмавання (напрыклад, Java) і фрэймворкаў (напрыклад, Spring Boot) усё гэта можна рэалізаваць, зусім не чапаючы сам код прыкладанняў. Так, код давядзецца злёгку мадыфікаваць, калі вы выкарыстоўваеце іншыя мовы, у першую чаргу маюцца на ўвазе Nodejs або C#. Але паколькі адсочванне (чытай, «трасіроўка») з'яўляецца адной з абавязковых умоў пры стварэнні надзейных хмарных сістэм, вам у любым выпадку давядзецца кіраваць код, ёсць у вас Istio ці не. Дык чаму б не выдаткаваць намаганні з большай карысцю?

Хаця б для таго, каб заўсёды адказваць на пытанні "дзе?" і "як хутка?" са 100% пэўнасцю.

Хаос-інжынірынг у Istio: так і было задумана

Уменне ламаць рэчы дапамагае зрабіць так, каб яны не ламаліся

Тэставанне софту - рэч не толькі складаная, але і важная. У той жа час тэставанне на карэктнасць (напрыклад, ці вяртае функцыя дакладны вынік) - гэта адно, а тэставанне ва ўмовах ненадзейнай сеткі - гэта зусім іншая задача (часта лічыцца, што сетка заўсёды працуе без збояў, і гэта найпершая з васьмі памылак адносна размеркаваных вылічэнняў). Адна са складанасцяў пры рашэнні гэтай задачы складаецца ў тым, як імітаваць збоі ў сістэме ці ўносіць іх наўмысна, выконваючы так званы fault injection. Гэта можна рабіць шляхам мадыфікацыі зыходнага кода самога дадатку. Але тады вы будзеце тэставаць ужо не свой першапачатковы код, а яго версію, якая спецыяльна імітуе збоі. У выніку вы рызыкуеце дагадзіць у смяротныя абдымкі fault injection і сутыкнуць з гейзенбагамі - збоямі, якія знікаюць пры спробе іх выявіць.

А зараз мы пакажам, як Istio дапамагае зладзіцца з гэтымі складанасцямі на раз-два.

Як усё выглядае, калі ўсё выдатна

Разгледзім наступны сцэнар: у нас есць два pod'а для нашага мікрасэрвісу recommendation, які мы ўзялі з падручніка па Istio. Адзін pod пазначаны як v1, а іншы як v2. Як бачым, пакуль усё працуе выдатна:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
(Дарэчы, лік справа - гэта проста лічыльнік выклікаў для кожнага pod'а)

Але нам жа трэба зусім не гэта, праўда? Што ж, паспрабуем усё зламаць, зусім не чапаючы зыходны код.

Уладкоўваем перабоі ў працы мікрасэрвісу

Ниже приведен yaml-файл для правила маршрутизации Istio, которое в половине случаев будет выдавать сбой (ошибку сервера 503):

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
Звярніце ўвагу, мы відавочна прапісваем, што ў палове выпадкаў мусіць вяртацца памылка 503.

А вось як будзе выглядаць скрыншот запушчанай у цыкле каманды curl пасля таго, як мы актывуем гэтае правіла, каб імітаваць збоі. Як бачым, палова запытаў вяртае памылку 503, прычым па-за залежнасцю ад таго, на які pod – v1 ці v2 – яны сыходзяць:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
Для аднаўлення нармальнай працы дастаткова выдаліць гэтае правіла, у нашым выпадку камандай istioctl delete routerule recommendation-503 -n tutorial. Тут Tutorial - гэта імя праекта Red Hat OpenShift, у якім працуе наш падручнік па Istio.

Уносім штучныя затрымкі

Штучныя памылкі 503 дапамагаюць пратэставаць сістэму на ўстойлівасць да збояў, але здольнасць прагназаваць і апрацоўваць затрымкі павінна ўразіць вас яшчэ больш. Ды і затрымкі ў рэальным жыцці здараюцца гушчару, чым збоі. Павольна які працуе мікрасэрвіс – гэта яд, ад якога пакутуе ўся сістэма. Дзякуючы Istio можна пратэставаць код, які адносіцца да апрацоўкі затрымак, ніяк яго пры гэтым не змяняючы. Для пачатку мы пакажам, як гэта зрабіць у выпадку штучна уведзеных затрымак сеткі.

Звярніце ўвагу, што пасля такога тэсціравання вам, магчыма, спатрэбіцца (ці захочацца) дапрацаваць свой код. Добрая навіна тут у тым, у гэтым выпадку вы будзеце дзейнічаць проактивно, а не рэактыўна. Менавіта так і павінен будавацца цыкл распрацоўкі: кадаванне-тэставанне-зваротная сувязь-кадаванне-тэставанне…

Вось як выглядае правіла, якое… Хаця ведаеце што? Istio такі просты, а гэты yaml-файл настолькі зразумелы, што ўсё ў гэтым прыкладзе гаворыць само за сябе, проста зірніце:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
У палове выпадкаў у нас будзе ўзнікаць 7-секундная затрымка. І гэта зусім не тое ж самае, як калі б мы ўставілі ў зыходны код каманду sleep, паколькі Istio рэальна затрымоўвае запыт на 7 секунд. Паколькі Istio падтрымлівае трасіроўку Jaeger, гэтая затрымка выдатна назіраецца ў Jaeger'оском UI, як паказана на скрыне ніжэй. Звярніце ўвагу на доўгі запыт у правым верхнім куце дыяграмы - яго працягласць складае 7.02 секунды:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
Гэты сцэнар дазваляе пратэставаць код ва ўмовах сеткавых затрымак. І зразумела, што, прыбраўшы гэтае правіла, мы прыбярэм штучную затрымку. Паўторымся, але мы зноў зрабілі ўсё гэта, ніяк не чапаючы зыходны код.

Не адступаць і не здавацца

Іншая карысная для хаос-інжынірынгу функцыя Istio – гэта паўторныя звароты да сэрвісу зададзены лік разоў. Сэнс тут у тым, каб не спыняць спробы, калі першы запыт заканчваецца памылкай 503 і тады, магчыма, у N-наццаты раз нам павязе. Можа быць, сэрвіс проста ненадоўга прылёг па тым ці іншым чынніку. Так, гэты чыннік трэба было б раскапаць і ўхіліць. Але гэта потым, а пакуль паспрабуем зрабіць так, каб сістэма працягвала працаваць.

Такім чынам, мы жадаем, каб сэрвіс час ад часу выдаваў памылку 503, а Istio пасля гэтага паўтараў спробы з ім звязацца. І тут відавочна патрэбен спосаб генераваць памылку 503, не чапаючы сам код…

Стоп, пачакайце! Мы ж толькі што гэта рабілі.

Вось гэты файл зробіць так, што сэрвіс recommendation-v2 будзе ў палове выпадкам выдаваць памылку 503:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
Відавочна, што частка запытаў будзе скончвацца няўдачай:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
А зараз задзейнічаем Istio-функцыю Retry:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
Гэтае правіла маршрутызацыі робіць тры паўторы з двухсекундным інтэрвалам і павінна скараціць (а ў ідэале і зусім прыбраць з радара) памылкі 503:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
Рэзюмуем: мы зрабілі так, што Istio, па-першае, генеруе памылку 503 для паловы запытаў. А па-другое, той жа Istio выконвае тры спробы паўторна звязацца з сэрвісам пры ўзнікненні памылкі 503. У выніку ўсё працуе проста выдатна. Такім чынам, выкарыстоўваючы функцыю Retry, мы выканалі сваё абяцанне не адыходзіць і не здавацца.

І так, мы зноў зрабілі гэта, зусім не чапаючы код. Усё, што нам спатрэбілася, - гэта два правілы маршрутызацыі Istio:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці

Як не падвесці карыстальніка ці сямёра аднаго не чакаюць

А зараз вывернем сітуацыю навыварат і разгледзім сцэнар, калі не адыходзіць і не здавацца варта толькі нейкі фіксаваны час. А затым трэба проста спыніць спробы апрацаваць запыт, каб не прымушаць усіх чакаць нейкага аднаго тармозіць сэрвісу. Інакш кажучы, мы не будзем абараняць страчаную пазіцыю, а адыдзем на запасную мяжу, каб не падводзіць карыстальніка сайта і не прымушаць яго стамляцца ў няведанні.

У Istio можна задаць таймаўт выканання запыту. Калі сэрвіс перавышае гэты таймаўт, вяртаецца памылка 504 (Gateway Timeout) - ізноў жа ўсё гэта робіцца праз канфігурацыю Istio. Але нам давядзецца дадаць у зыходны код сэрвісу каманду sleep (а затым, вядома, выканаць rebuild і redeploy), каб імітаваць павольную працу сэрвісу. Нажаль, інакш не атрымаецца.

Такім чынам, мы ўставілі трохсекундны sleep у код сэрвісу recommendation v2, перасабралі адпаведную выяву і зрабілі рэдэплой кантэйнера, а зараз дадамо таймаўт з дапамогай наступнага правіла маршрутызацыі Istio:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
На скрыне вышэй відаць, што мы кідаем спробы звязацца з сэрвісам recommendation, калі не атрымліваем адказу на працягу адной секунды, гэта значыць яшчэ да таго, як паўстане памылка 504. Пасля ўжывання гэтага правіла маршрутызацыі (і даданні трохсекунднага sleep'а ў код сэрвісу recommendation:v2), мы атрымаем вось што:

Трасіроўка і маніторынг у Istio: мікрасэрвісы і прынцып нявызначанасці
Ізноў паўтараемся, але таймаўт можна задаць, ніяк не чапаючы зыходны код. А дадатковы бонус тут у тым, што зараз вы можаце мадыфікаваць свой код так, каб ён рэагаваў на таймаўт, і лёгка пратэставаць гэтыя дапрацоўкі з дапамогай Istio.

А зараз усё разам

Унесці трохі хаосу з дапамогай Istio – гэта выдатны спосаб пратэставаць ваш код і надзейнасць вашай сістэмы ў цэлым. будучыню.

Крыніца: habr.com

Купіць надзейны хостынг для сайтаў з абаронай ад DDoS, VPS VDS серверы 🔥 Купіць надзейны хостынг для сайтаў з абаронай ад DDoS, VPS VDS серверы | ProHoster