{"id":52389,"date":"2019-11-07T00:00:00","date_gmt":"2019-11-06T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions"},"modified":"2020-02-18T14:00:05","modified_gmt":"2020-02-18T11:00:05","slug":"kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions","status":"publish","type":"post","link":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions","title":{"rendered":"Cum se realizeaz\u0103 arhitectura web tolerante la erori \u00een platforma Mail.ru Cloud Solutions","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Cum se realizeaz\u0103 arhitectura web tolerante la erori \u00een platforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/fe7af07f3ac5ca4e75009993b742293e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nBun\u0103, Habr! Eu sunt Artiom Karami\u0219ev, liderul echipei de administrare a sistemelor <noindex><a rel=\"nofollow\" href=\"https:\/\/mcs.mail.ru\/\">Mail.Ru Cloud Solutions (MCS)<\/a><\/noindex>. \u00cen ultimul an, am avut multe lans\u0103ri de produse noi. Am dorit s\u0103 ne asigur\u0103m c\u0103 serviciile API sunt u\u0219or scalabile, tolerante la erori \u0219i preg\u0103tite pentru cre\u0219terea rapid\u0103 a \u00eenc\u0103rc\u0103turii utilizatorilor. Platforma noastr\u0103 este realizat\u0103 pe OpenStack \u0219i vreau s\u0103 v\u0103 povestesc despre problemele de toleran\u021b\u0103 la erori ale componentelor pe care a trebuit s\u0103 le rezolv\u0103m pentru a ob\u021bine un sistem tolerante la erori. Cred c\u0103 va fi interesant pentru cei care dezvolt\u0103 \u0219i produse pe OpenStack.<\/p>\n<p>Toleran\u021ba general\u0103 la erori a platformei este format\u0103 din rezisten\u021ba componentelor sale. A\u0219a c\u0103 vom parcurge treptat toate nivelurile la care am identificat riscuri \u0219i le-am rezolvat.<\/p>\n<p>Versiunea video a acestei pove\u0219ti, care a avut ca surs\u0103 o prezentare de la conferin\u021ba Uptime day 4, organizat\u0103 de <noindex><a rel=\"nofollow\" href=\"http:\/\/www.itsumma.ru\">ITSumma<\/a><\/noindex>, poate fi vizionat\u0103 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=3b06MVou-vg&amp;list=PLmXjIrLllpkjwuIGkzBkLbI7oHtUadmvZ&amp;index=5\">pe canalul YouTube Uptime Community<\/a><\/noindex>. <br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Toleran\u021ba la erori a arhitecturii fizice<\/h2>\n<p>\nPartea public\u0103 a cloud-ului MCS se bazeaz\u0103 acum pe dou\u0103 centre de date de nivel Tier III, \u00eentre care exist\u0103 fibr\u0103 optic\u0103 proprie, rezervat\u0103 la nivel fizic pe diferite trasee, cu o l\u0103\u021bime de band\u0103 de 200 Gbit\/s. Nivelul Tier III asigur\u0103 nivelul necesar de toleran\u021b\u0103 la erori pentru infrastructura fizic\u0103. <\/p>\n<p>Fibr\u0103 optic\u0103 este rezervat\u0103 at\u00e2t la nivel fizic, c\u00e2t \u0219i la nivel logic. Procesul de rezervare a canalelor a fost iterativ, au ap\u0103rut probleme, iar noi \u00eembun\u0103t\u0103\u021bim constant conexiunea \u00eentre centrele de date. <\/p>\n<blockquote><p>De exemplu, nu cu mult timp \u00een urm\u0103, \u00een timpul lucr\u0103rilor \u00eentr-o fosa din apropierea unuia dintre centrele de date, o excavatoare a perforat un tub, iar \u00een interiorul acestui tub se afla at\u00e2t cablul optic principal, c\u00e2t \u0219i cel de rezerv\u0103. Canalul nostru de comunica\u021bie tolerant la erori cu centrul de date a fost vulnerabil \u00eentr-un singur punct, \u00een fosa. Prin urmare, am pierdut o parte din infrastructur\u0103. Am \u00eenv\u0103\u021bat din aceasta, am luat o serie de m\u0103suri, inclusiv am tras o fibr\u0103 optic\u0103 suplimentar\u0103 prin fosa vecin\u0103.<\/p><\/blockquote>\n<p>\nCentrele de date au puncte de prezen\u021b\u0103 ale furnizorilor de servicii, c\u0103rora le transmitem prefixelor noastre prin BGP. Pentru fiecare direc\u021bie de re\u021bea se alege cea mai bun\u0103 metric\u0103, ceea ce permite asigurarea unei calit\u0103\u021bi superioare a conexiunii pentru diferi\u021bi clien\u021bi. Dac\u0103 conexiunea printr-un furnizor se \u00eentrerupe, ne reconfigur\u0103m rutarea prin furnizorii disponibili.<\/p>\n<p>\u00cen caz de defec\u021biune a furnizorului, trecem automat la urm\u0103torul. \u00cen cazul unei defec\u021biuni a unuia dintre centrele de date, avem o copie mirror a serviciilor noastre \u00een cel de-al doilea centru de date, care preia \u00eentreaga sarcin\u0103.<\/p>\n<p><img decoding=\"async\" alt=\"Cum se realizeaz\u0103 arhitectura web tolerante la erori \u00een platforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/295ca212f48dd074d834154666e5b0c3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Rezisten\u021ba la defec\u021biuni a infrastructurii fizice<\/i><\/p>\n<h2>Ce utiliz\u0103m pentru rezisten\u021ba la defec\u021biuni la nivel de aplica\u021bii<\/h2>\n<p>\nServiciul nostru este construit pe baza unui num\u0103r de componente open-source. <\/p>\n<p><b>ExaBGP<\/b> \u2014 un serviciu care implementeaz\u0103 o serie de func\u021bii folosind protocolul de rutare dinamic bazat pe BGP. \u00cel folosim activ pentru a anun\u021ba adresele noastre IP albe, prin care utilizatorii acceseaz\u0103 API-ul.<\/p>\n<p><b>HAProxy<\/b> \u2014 un echilibrist de sarcin\u0103 de mare capacitate, care permite configurarea unor reguli foarte flexibile de echilibrare a traficului la diferite niveluri ale modelului OSI. \u00cel folosim pentru echilibrarea \u00een fa\u021ba tuturor serviciilor: baze de date, brokeri de mesaje, servicii API, servicii web, proiecte interne \u2014 totul se afl\u0103 \u00een spatele HAProxy.<\/p>\n<p><b>Aplica\u021bia API<\/b> \u2014 o aplica\u021bie web scris\u0103 \u00een Python, prin care utilizatorul \u00ee\u0219i gestioneaz\u0103 infrastructura \u0219i serviciul.<\/p>\n<p><b>Aplica\u021bia Worker <\/b>(denumit\u0103 \u00een continuare simplu worker) \u2014 \u00een serviciile OpenStack, aceasta este un daemon de infrastructur\u0103 care permite transmiterea comenzilor API c\u0103tre infrastructur\u0103. De exemplu, crearea unui disc are loc exact \u00een worker, iar cererea de creare \u2014 \u00een aplica\u021bia API. <\/p>\n<h2>Arhitectura standard a aplica\u021biei OpenStack<\/h2>\n<p>\nCele mai multe servicii dezvoltate pentru OpenStack \u00eencearc\u0103 s\u0103 urmeze o paradigm\u0103 unitar\u0103. Un serviciu const\u0103 de obicei din 2 p\u0103r\u021bi: API \u0219i workeri (executoare de backend). \u00cen general, API-ul este o aplica\u021bie WSGI scris\u0103 \u00een Python, care este rulat\u0103 fie ca un proces independent (daemon), fie cu ajutorul unui server web existent, cum ar fi Nginx sau Apache. API-ul proceseaz\u0103 cererea utilizatorului \u0219i transmite instruc\u021biunile suplimentare aplica\u021biei worker. Transmiterea se face prin intermediul unui broker de mesaje, de cele mai multe ori RabbitMQ, celelalte fiind mai pu\u021bin suportate. C\u00e2nd mesajele ajung \u00een broker, acestea sunt procesate de workerii care, dac\u0103 este necesar, returneaz\u0103 un r\u0103spuns. <\/p>\n<p>Aceast\u0103 paradigm\u0103 implic\u0103 puncte de defec\u021biune izolate: RabbitMQ \u0219i baza de date. Totu\u0219i, RabbitMQ este izolat \u00een cadrul unui singur serviciu \u0219i, \u00een teorie, poate fi individual pentru fiecare serviciu. A\u0219a c\u0103, \u00een MCS, separ\u0103m la maxim aceste servicii; pentru fiecare proiect separat cre\u0103m o baz\u0103 de date distinct\u0103, un RabbitMQ separat. Aceast\u0103 abordare este eficient\u0103 deoarece, \u00een cazul unei avarii \u00een c\u00e2teva puncte vulnerabile, nu se defecteaz\u0103 \u00eentregul serviciu, ci doar partea sa.<\/p>\n<p>Num\u0103rul de aplica\u021bii worker nu este limitat, a\u0219a c\u0103 API-ul poate fi u\u0219or scalat orizontal prin intermediul echilibratorilor de sarcin\u0103 pentru a cre\u0219te performan\u021ba \u0219i rezisten\u021ba la defec\u021biuni.<\/p>\n<blockquote><p>\u00cen unele servicii este necesar\u0103 coordonarea \u00een cadrul serviciului \u2014 atunci c\u00e2nd au loc opera\u021biuni succesive complexe \u00eentre API \u0219i lucr\u0103tori. \u00cen acest caz, se folose\u0219te un centru unic de coordonare, un sistem de cluster de tip Redis, Memcache, etcd, care permite unui lucr\u0103tor s\u0103-i spun\u0103 altuia c\u0103 aceast\u0103 sarcin\u0103 \u00eei este atribuit\u0103 (\u201ete rog, nu o lua\u201d). Noi folosim etcd. De obicei, lucr\u0103torii comunic\u0103 activ cu baza de date, scriind \u0219i citind informa\u021bii din aceasta. Ca baz\u0103 de date, utiliz\u0103m mariadb, care se afl\u0103 \u00eentr-un cluster multimaster.\n<\/p><\/blockquote>\n<p>\nUn astfel de serviciu clasic unic este organizat \u00eentr-un mod standard acceptat pentru OpenStack. Poate fi considerat un sistem \u00eenchis, pentru care metodele de scalare \u0219i rezisten\u021b\u0103 la defec\u021biuni sunt destul de evidente. De exemplu, pentru rezisten\u021ba la defec\u021biuni a API-ului, este suficient s\u0103 se plaseze un equilibrator de sarcin\u0103 \u00een fa\u021ba acestora. Scalarea workerilor se realizeaz\u0103 prin cre\u0219terea num\u0103rului acestora. <\/p>\n<p>Punctul slab din \u00eentreaga schem\u0103 este RabbitMQ \u0219i MariaDB. Arhitectura lor merit\u0103 un articol separat. \u00cen acest articol vreau s\u0103 m\u0103 concentrez pe rezilien\u021ba API-ului.<\/p>\n<p><img decoding=\"async\" alt=\"Cum se realizeaz\u0103 arhitectura web tolerante la erori \u00een platforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/f39e5a8ae350864e311bf4db3b9c34b3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Arhitectura Openstack Application. Echilibrarea \u0219i rezilien\u021ba platformei de cloud.<\/i><\/p>\n<h2>Facem echilibratorul HAProxy rezilient cu ajutorul ExaBGP.<\/h2>\n<p>\nPentru ca API-urile noastre s\u0103 fie scalabile, rapide \u0219i reziliente, le-am pus un echilibrator \u00een fa\u021b\u0103. Am ales HAProxy. Din punctul meu de vedere, acesta are toate caracteristicile necesare pentru sarcina noastr\u0103: echilibrare pe mai multe niveluri OSI, interfa\u021b\u0103 de management, flexibilitate \u0219i scalabilitate, un num\u0103r mare de metode de echilibrare, suport pentru tabelele de sesiune.<\/p>\n<p>Prima problem\u0103 pe care a trebuit s\u0103 o rezolv\u0103m a fost rezilien\u021ba echilibratorului \u00een sine. Simpl\u0103 instalare a echilibratorului creeaz\u0103 de asemenea un punct de e\u0219ec: dac\u0103 echilibratorul pic\u0103, serviciul se \u00eentrerupe. Pentru a evita acest lucru, am folosit HAProxy \u00eempreun\u0103 cu ExaBGP.<\/p>\n<p>ExaBGP permite implementarea unui mecanism de verificare a st\u0103rii serviciului. Am folosit acest mecanism pentru a verifica func\u021bionarea HAProxy \u0219i, \u00een caz de probleme, a dezactiva serviciul HAProxy din BGP. <\/p>\n<p><b>Schema ExaBGP+HAProxy.<\/b><\/p>\n<ol>\n<li>Instal\u0103m pe trei servere software-ul necesar, ExaBGP \u0219i HAProxy. <\/li>\n<li>Pe fiecare dintre servere, cre\u0103m o interfa\u021b\u0103 loopback.<\/li>\n<li>Pe toate cele trei servere, configur\u0103m acelea\u0219i adrese IP publice pentru aceast\u0103 interfa\u021b\u0103.<\/li>\n<li>Adresa IP public\u0103 este anun\u021bat\u0103 \u00een internet prin ExaBGP. <\/li>\n<\/ol>\n<p>\nRezilien\u021ba se ob\u021bine prin anun\u021barea acelea\u0219i adrese IP de pe toate cele trei servere. Din punct de vedere al re\u021belei, aceea\u0219i adres\u0103 este disponibil\u0103 din trei next hop-uri diferite. Routerul vede trei rute identice, alege cea mai prioritar\u0103 \u00een func\u021bie de metricile proprii (de obicei aceea\u0219i op\u021biune) \u0219i traficul merge doar pe unul dintre servere. <\/p>\n<p>\u00cen caz de probleme cu func\u021bionarea HAProxy sau c\u0103derea unui server, ExaBGP \u00eenceteaz\u0103 s\u0103 anun\u021be ruta, iar traficul se comut\u0103 lin pe alt server. <\/p>\n<p>Astfel, am ob\u021binut rezilien\u021ba echilibratorului.<\/p>\n<p><img decoding=\"async\" alt=\"Cum se realizeaz\u0103 arhitectura web tolerante la erori \u00een platforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/9fba0718176dc1266f25a2c01ec87348.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Rezilien\u021ba echilibratoarelor HAProxy.<\/i><\/p>\n<p>Schema rezultat\u0103 nu este ideal\u0103: am \u00eenv\u0103\u021bat s\u0103 rezerv\u0103m HAProxy, dar nu am \u00eenv\u0103\u021bat s\u0103 distribuim sarcina \u00een interiorul serviciilor. De aceea, am extins pu\u021bin schema: am trecut la echilibrarea \u00eentre mai multe adrese IP publice.<\/p>\n<h2>Echilibrarea bazat\u0103 pe DNS plus BGP<\/h2>\n<p>\n\u00centrebarea echilibr\u0103rii sarcinii \u00eenaintea HAProxy-urilor noastre a r\u0103mas nerezolvat\u0103. Cu toate acestea, poate fi rezolvat\u0103 destul de simplu, a\u0219a cum am procedat \u0219i noi.<\/p>\n<p>Pentru echilibrarea a trei servere sunt necesare 3 adrese IP publice \u0219i vechiul DNS. Fiecare dintre aceste adrese este definit\u0103 pe interfa\u021ba loopback a fiec\u0103rui HAProxy \u0219i este anun\u021bat\u0103 pe Internet. <\/p>\n<p>\u00cen OpenStack, pentru gestionarea resurselor se folose\u0219te un catalog de servicii, \u00een care este definit endpoint-ul API pentru fiecare serviciu. \u00cen acest catalog, specific\u0103m numele de domeniu \u2014 public.infra.mail.ru, care este rezolvat prin DNS prin trei adrese IP diferite. Ca urmare, ob\u021binem distribu\u021bia sarcinii \u00eentre cele trei adrese prin intermediul DNS. <\/p>\n<p>Dar, deoarece nu gestion\u0103m priorit\u0103\u021bile de selectare a serverelor \u00een timpul anun\u021b\u0103rii adreselor IP publice, nu este \u00eenc\u0103 o echilibrare. De obicei, va fi selectat un singur server \u00een func\u021bie de senioritatea adresei IP, iar celelalte dou\u0103 vor sta \u00een a\u0219teptare, deoarece nu sunt specificate metriki \u00een BGP.<\/p>\n<p>Am \u00eenceput s\u0103 anun\u021b\u0103m rutele prin ExaBGP cu metrici diferite. Fiecare echilibror anun\u021b\u0103 toate cele trei adrese IP publice, dar unul dintre ele, principal pentru acest echilibror, este anun\u021bat cu cea mai mic\u0103 metric\u0103. A\u0219adar, c\u00e2t timp toate cele trei echilibratoare sunt func\u021bionale, cererile c\u0103tre prima adres\u0103 IP ajung la primul echilibror, cererile c\u0103tre a doua la al doilea, iar cele c\u0103tre a treia la al treilea.<\/p>\n<p>Ce se \u00eent\u00e2mpl\u0103 \u00een momentul \u00een care unul dintre echilibratoare se opre\u0219te? \u00cen cazul \u00een care oricare dintre echilibratoare e\u0219ueaz\u0103, adresa sa principal\u0103 este \u00eenc\u0103 anun\u021bat\u0103 de celelalte dou\u0103, iar traficul \u00eentre ele se redistribuie. Astfel, oferim utilizatorului prin DNS imediat c\u00e2teva adrese IP. Prin echilibrarea pe DNS \u0219i metrici diferite ob\u021binem o distribu\u021bie uniform\u0103 a sarcinii pe toate cele trei echilibratoare. \u0218i, \u00een acela\u0219i timp, nu pierdem rezisten\u021ba la defec\u021biuni.<\/p>\n<p><img decoding=\"async\" alt=\"Cum se realizeaz\u0103 arhitectura web tolerante la erori \u00een platforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/1485367a934aea06b68c6d05c184d263.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Echilibrarea HAProxy pe baza DNS + BGP<\/i><\/p>\n<h2>Interac\u021biunea \u00eentre ExaBGP \u0219i HAProxy<\/h2>\n<p>\nA\u0219adar, am implementat rezisten\u021ba la defec\u021biuni \u00een cazul \u00een care un server pleac\u0103, pe baza \u00eencet\u0103rii anun\u021b\u0103rii rutelor. Dar HAProxy se poate opri \u0219i din alte motive dec\u00e2t defec\u021biunea serverului: erori de administrare, defec\u021biuni interne ale serviciului. Vrem s\u0103 elimin\u0103m echilibrorul defect de sub sarcin\u0103 \u0219i \u00een aceste cazuri, \u0219i este necesar un alt mecanism. <\/p>\n<p>Prin urmare, extinz\u00e2nd schema precedent\u0103, am implementat un heartbeat \u00eentre ExaBGP \u0219i HAProxy. Aceasta este o implementare software a interac\u021biunii \u00eentre ExaBGP \u0219i HAProxy, \u00een care ExaBGP folose\u0219te scripturi personalizate pentru a verifica starea aplica\u021biilor.<\/p>\n<p>Pentru aceasta, \u00een configura\u021bia ExaBGP trebuie s\u0103 configur\u0103m un health checker care s\u0103 poat\u0103 verifica starea HAProxy. \u00cen cazul nostru, am configurat un health backend \u00een HAProxy, iar din partea ExaBGP verific\u0103m printr-un simplu GET request. Dac\u0103 anun\u021bul \u00eenceteaz\u0103 s\u0103 mai aib\u0103 loc, atunci HAProxy, cel mai probabil, nu func\u021bioneaz\u0103 \u0219i nu trebuie s\u0103-l anun\u021b\u0103m. <\/p>\n<p><img decoding=\"async\" alt=\"Cum se realizeaz\u0103 arhitectura web tolerante la erori \u00een platforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/d5cda30043fe02ab81355b28c0d83ac6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Verificare a s\u0103n\u0103t\u0103\u021bii HAProxy<\/i><\/p>\n<h2>Perechi HAProxy: sincronizarea sesiunilor <\/h2>\n<p>\nUrm\u0103torul lucru pe care trebuia s\u0103-l facem era s\u0103 sincroniz\u0103m sesiunile. Atunci c\u00e2nd lucr\u0103m prin balansoare distribuite, este greu s\u0103 organiz\u0103m p\u0103strarea informa\u021biilor despre sesiunile clien\u021bilor. \u00cens\u0103 HAProxy este unul dintre pu\u021binele balansoare care pot face acest lucru datorit\u0103 func\u021bionalit\u0103\u021bii Peers \u2013 capacitatea de a transfera \u00eentre diferitele procese HAProxy tabelele de sesiuni. <\/p>\n<p>Exist\u0103 diferite metode de balansare: simple, cum ar fi <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Round-robin_(%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC)\">round-robin<\/a><\/noindex>, \u0219i avansate, \u00een care sesiunea clientului este p\u0103strat\u0103, iar acesta ajunge de fiecare dat\u0103 pe acela\u0219i server pe care l-a folosit anterior. Noi am dorit s\u0103 implement\u0103m a doua variant\u0103.<\/p>\n<p>\u00cen HAProxy, pentru p\u0103strarea sesiunilor clientului, acest mecanism folose\u0219te stick-tables. Acestea p\u0103streaz\u0103 adresa IP ini\u021bial\u0103 a clientului, adresa \u021bint\u0103 aleas\u0103 (backend) \u0219i unele informa\u021bii de serviciu. De obicei, stick-tables sunt utilizate pentru a p\u0103stra perechea source-IP + destination-IP, ceea ce este deosebit de util pentru aplica\u021biile care nu pot transmite contextul sesiunii utilizatorului atunci c\u00e2nd trec pe un alt balansoar, de exemplu \u2013 \u00een modul de balansare RoundRobin.<\/p>\n<p>Dac\u0103 stick-table este \u00eenv\u0103\u021bat\u0103 s\u0103 se mi\u0219te \u00eentre diferitele procese HAProxy (\u00eentre care se efectueaz\u0103 balansarea), balansoarele noastre vor putea lucra cu un singur pool de stick-tables. Aceasta va permite comutarea f\u0103r\u0103 probleme a re\u021belei clientului \u00een cazul \u00een care unul dintre balansoare cedeaz\u0103, iar lucrul cu sesiunile clien\u021bilor va continua pe acelea\u0219i backends care au fost alese anterior.<\/p>\n<p>Pentru a func\u021biona corect, trebuie rezolvat\u0103 problema adresei IP surs\u0103 a balansoarului de la care a fost stabilit\u0103 sesiunea. \u00cen cazul nostru, aceasta este o adres\u0103 dinamic\u0103 pe interfa\u021ba loopback. <\/p>\n<p>Func\u021bionarea corect\u0103 a peers se realizeaz\u0103 doar \u00een anumite condi\u021bii. Asta \u00eenseamn\u0103 c\u0103 timeout-urile TCP trebuie s\u0103 fie suficient de mari sau comutarea trebuie s\u0103 fie suficient de rapid\u0103 pentru a preveni \u00eentreruperea sesiunii TCP. Cu toate acestea, acest lucru permite comutarea f\u0103r\u0103 \u00eentreruperi. <\/p>\n<p>Avem \u00een IaaS un serviciu construit pe aceea\u0219i tehnologie. Acesta <noindex><a rel=\"nofollow\" href=\"https:\/\/mcs.mail.ru\/app\/services\/infra\/balancers-list\/\">Load Balancer ca serviciu pentru OpenStack<\/a><\/noindex>, numit Octavia. Este bazat pe dou\u0103 procese HAProxy, av\u00e2nd suport ini\u021bial pentru peers. \u00cen acest serviciu, acestea s-au demonstrat a fi foarte eficiente.<\/p>\n<p>\u00cen imagine este reprezentat\u0103 schematic mi\u0219carea tabelelor peers \u00eentre cele trei instan\u021be HAProxy, fiind propus un configurare pentru cum poate fi realizat\u0103 aceast\u0103 setare:<\/p>\n<p><img decoding=\"async\" alt=\"Cum se realizeaz\u0103 arhitectura web tolerante la erori \u00een platforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/d31fab761da627923345b7ace7f0b943.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>HAProxy Peers (sincronizarea sesiunilor)<\/i><\/p>\n<p>Dac\u0103 inten\u021biona\u021bi s\u0103 implementa\u021bi o asemenea schem\u0103, este necesar s\u0103 testa\u021bi cu aten\u021bie func\u021bionarea acesteia. Nu este garantat c\u0103 va func\u021biona \u00een acelea\u0219i condi\u021bii \u00een 100% din cazuri. Dar, cel pu\u021bin, nu ve\u021bi pierde stick-tabelele atunci c\u00e2nd trebuie s\u0103 re\u021bine\u021bi IP-ul surs\u0103 al clientului.<\/p>\n<h2>Limitarea num\u0103rului de cereri simultane de la acela\u0219i client<\/h2>\n<p>\nOrice servicii aflate \u00een acces deschis, inclusiv API-urile noastre, pot fi supuse avalan\u0219elor de cereri. Motivele pot varia de la erori ale utilizatorilor p\u00e2n\u0103 la atacuri deliberate. Noi suntem periodic DDoS-a\u021bi pe adresele IP. Clien\u021bii gre\u0219esc frecvent \u00een scripturile lor, provoc\u00e2nd mini-DDoS-uri.<\/p>\n<p>Indiferent de caz, este necesar s\u0103 prevedem o protec\u021bie suplimentar\u0103. O solu\u021bie evident\u0103 devine limitarea num\u0103rului de cereri c\u0103tre API \u0219i evitarea pierderii timpului CPU pe procesarea cererilor mali\u021bioase.<\/p>\n<p>Pentru implementarea unor astfel de limit\u0103ri, aplic\u0103m rate limits, organizate pe baza HAProxy, cu ajutorul acelora\u0219i stick-tabele. Limitele pot fi setate destul de simplu \u0219i permit restric\u021bionarea utilizatorului \u00een func\u021bie de num\u0103rul de cereri c\u0103tre API. Algoritmul \u00ee\u0219i re\u021bine IP-ul surs\u0103 de unde sunt efectuate cererile \u0219i limiteaz\u0103 num\u0103rul de cereri simultane de la un singur utilizator. Fire\u0219te, am calculat profilul mediu de \u00eenc\u0103rcare pe API pentru fiecare serviciu \u0219i am stabilit o limit\u0103 de aproximativ 10 ori mai mare dec\u00e2t aceast\u0103 valoare. Continu\u0103m s\u0103 monitoriz\u0103m cu aten\u021bie situa\u021bia, av\u00e2nd m\u00e2na pe puls.<\/p>\n<p>Cum arat\u0103 \u00een practic\u0103? Avem clien\u021bi care folosesc constant API-urile noastre pentru scalarea automat\u0103. Ace\u0219tia creeaz\u0103 aproximativ dou\u0103 sute-trei sute de ma\u0219ini virtuale diminea\u021ba \u0219i le \u0219terg seara. Pentru OpenStack, a crea o ma\u0219in\u0103 virtual\u0103, \u00eempreun\u0103 cu servicii PaaS, \u00eenseamn\u0103 cel pu\u021bin 1000 de cereri API, deoarece interac\u021biunea \u00eentre servicii se face \u0219i prin API. <\/p>\n<p>Astfel de transferuri de sarcini genereaz\u0103 o sarcin\u0103 considerabil\u0103. Am evaluat aceast\u0103 sarcin\u0103, am colectat v\u00e2rfurile zilnice, le-am \u00eenmul\u021bit cu zece \u0219i aceasta a devenit limita noastr\u0103 de rat\u0103. Suntem mereu aten\u021bi la schimb\u0103ri. Vedem adesea robo\u021bi \u0219i scannere care \u00eencearc\u0103 s\u0103 ne verifice, c\u0103ut\u00e2nd dac\u0103 avem vreo script CGA pe care s\u0103 o poat\u0103 rula, pe care le t\u0103iem activ.<\/p>\n<h2>Cum s\u0103 actualiz\u0103m baza de cod f\u0103r\u0103 ca utilizatorii s\u0103 observe<\/h2>\n<p>\nImplement\u0103m redundan\u021ba \u0219i la nivelul proceselor de desf\u0103\u0219urare a codului. \u00cen timpul desf\u0103\u0219ur\u0103rilor apar erori, dar impactul acestora asupra disponibilit\u0103\u021bii serviciilor poate fi minimizat.<\/p>\n<p>Actualiz\u0103m constant serviciile noastre \u0219i trebuie s\u0103 asigur\u0103m un proces de actualizare a bazei de cod f\u0103r\u0103 efecte pentru utilizatori. Am reu\u0219it s\u0103 abord\u0103m aceast\u0103 problem\u0103, folosind capabilit\u0103\u021bile de gestionare HAProxy \u0219i implementarea Graceful Shutdown \u00een serviciile noastre.<\/p>\n<p>Pentru a rezolva aceast\u0103 problem\u0103, a fost necesar s\u0103 asigur\u0103m gestionarea balansorului de sarcin\u0103 \u0219i oprirea \u00abcorect\u0103\u00bb a serviciilor:<\/p>\n<ul>\n<li>\u00cen cazul HAProxy, gestionarea se face prin intermediul fi\u0219ierului stats, care este practic un socket \u0219i este definit \u00een configura\u021bia HAProxy. Comenzile pot fi transmise prin stdio. Dar principalul nostru instrument de control al configura\u021biilor este ansible, care are un modul integrat pentru gestionarea HAProxy. Pe care \u00eel folosim activ. <\/li>\n<li>Majoritatea serviciilor noastre API \u0219i Engine suport\u0103 tehnologiile de \u00eenchidere gra\u021bioas\u0103: la oprire, acestea a\u0219teapt\u0103 finalizarea complet\u0103 a sarcinii curente, fie c\u0103 este vorba de o cerere http sau de o sarcin\u0103 de \u00eentre\u021binere. Acela\u0219i lucru se \u00eent\u00e2mpl\u0103 \u0219i cu lucr\u0103torul. El \u0219tie toate sarcinile pe care le execut\u0103 \u0219i se opre\u0219te atunci c\u00e2nd le-a finalizat pe toate cu succes. <\/li>\n<\/ul>\n<p>\nDatorit\u0103 acestor dou\u0103 aspecte, algoritmul nostru de desf\u0103\u0219urare \u00een siguran\u021b\u0103 arat\u0103 astfel.<\/p>\n<ol>\n<li>Dezvoltatorul adun\u0103 un nou pachet de cod (pentru noi, acesta este RPM), \u00eel testeaz\u0103 \u00een mediul dev, \u00eel testeaz\u0103 \u00een stage \u0219i \u00eel las\u0103 \u00een depozitul stage.<\/li>\n<li>Dezvoltatorul stabile\u0219te sarcina de desf\u0103\u0219urare cu o descriere c\u00e2t mai detaliat\u0103 a \u201eartefactelor\u201d: versiunea noului pachet, descrierea noilor func\u021bionalit\u0103\u021bi \u0219i alte detalii despre desf\u0103\u0219urare, dac\u0103 este necesar.<\/li>\n<li>Administratorul de sistem porne\u0219te actualizarea. Lanseaz\u0103 playbook-ul Ansible, care la r\u00e2ndul s\u0103u face urm\u0103toarele: \n<ul>\n<li>Ia pachetul din repo-ul de stage \u0219i actualizeaz\u0103 versiunea pachetului \u00een repo-ul de produc\u021bie.<\/li>\n<li>Compune o list\u0103 a backend-urilor serviciului care urmeaz\u0103 s\u0103 fie actualizat.<\/li>\n<li>Opre\u0219te primul serviciu actualizat \u00een HAProxy \u0219i a\u0219teapt\u0103 finalizarea proceselor acestuia. Datorit\u0103 \u00eenchiderii elegante, suntem siguri c\u0103 toate cererile curente ale clien\u021bilor se vor finaliza cu succes.<\/li>\n<li>Dup\u0103 oprirea complet\u0103 a API-ului, a lucr\u0103torilor \u0219i a opririi HAProxy, are loc actualizarea codului.<\/li>\n<li>Ansible porne\u0219te serviciile.<\/li>\n<li>Pentru fiecare serviciu, trage anumite \u201em\u00e2nere\u201d care efectueaz\u0103 testare unitate bazat\u0103 pe un set de teste predefinite. Se realizeaz\u0103 o verificare de baz\u0103 a noului cod.<\/li>\n<li>Dac\u0103 nu au fost descoperite erori \u00een pasul anterior, backend-ul este activat.<\/li>\n<li>Trecem la urm\u0103torul backend.<\/li>\n<\/ul>\n<\/li>\n<li>Dup\u0103 actualizarea tuturor backend-urilor, sunt lansate teste func\u021bionale. Dac\u0103 sunt insuficiente, dezvoltatorul verific\u0103 orice nou\u0103 func\u021bionalitate pe care a realizat-o.<\/li>\n<\/ol>\n<p>\nAceasta \u00eenseamn\u0103 c\u0103 desf\u0103\u0219urarea s-a finalizat.<\/p>\n<p><img decoding=\"async\" alt=\"Cum se realizeaz\u0103 arhitectura web tolerante la erori \u00een platforma Mail.ru Cloud Solutions\" src=\"\/wp-content\/uploads\/2019\/11\/2d889fe1af33653e4bfebabe1cce6552.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Ciclul de actualizare a serviciului<\/i><\/p>\n<p>Aceast\u0103 schem\u0103 nu ar fi func\u021bional\u0103 dac\u0103 nu am avea o regul\u0103. Men\u021binem \u00een produc\u021bie simultan versiunea veche \u0219i pe cea nou\u0103. \u00cen prealabil, \u00een etapa de dezvoltare a software-ului, se presupune c\u0103, chiar dac\u0103 vor ap\u0103rea modific\u0103ri \u00een baza de date a serviciului, acestea nu vor afecta codul anterior. Ca urmare, se realizeaz\u0103 o actualizare treptat\u0103 a bazei de cod.<\/p>\n<h2>Concluzie<\/h2>\n<p>\n\u00cemp\u0103rt\u0103\u0219ind propriile g\u00e2nduri despre arhitectura WEB rezistent\u0103 la erori, vreau s\u0103 subliniez din nou punctele sale cheie:<\/p>\n<ul>\n<li>rezisten\u021ba fizic\u0103 la erori;<\/li>\n<li>rezisten\u021ba la erori a re\u021belei (\u00eenc\u0103rc\u0103toare, BGP);<\/li>\n<li>rezisten\u021ba la erori a software-ului utilizat \u0219i dezvoltat.<\/li>\n<\/ul>\n<p>\nToat\u0103 lumea s\u0103 aib\u0103 uptime stabil!<br \/>\n<br \/>Sursa: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/mailru\/blog\/474180\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u042f \u0410\u0440\u0442\u0435\u043c \u041a\u0430\u0440\u0430\u043c\u044b\u0448\u0435\u0432, \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Mail.Ru Cloud Solutions (MCS). \u0417\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0433\u043e\u0434 \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b\u043e \u043c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u0432 \u043d\u043e\u0432\u044b\u0445 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432. \u041c\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e\u0431\u044b API-\u0441\u0435\u0440\u0432\u0438\u0441\u044b \u043b\u0435\u0433\u043a\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043b\u0438\u0441\u044c, \u0431\u044b\u043b\u0438 \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u043c\u0438 \u0438 \u0433\u043e\u0442\u043e\u0432\u044b\u043c\u0438 \u043a \u0431\u044b\u0441\u0442\u0440\u043e\u043c\u0443 \u0440\u043e\u0441\u0442\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438. \u041d\u0430\u0448\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 OpenStack, \u0438 \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043d\u0430\u043c \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0437\u0430\u043a\u0440\u044b\u0442\u044c, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-52389","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\".\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u0430\u044f \u0432\u0435\u0431-\u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0432 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 Mail.ru Cloud Solutions | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\".\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-11-06T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:00:05+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Cum este implementat\u0103 arhitectura web rezistent\u0103 la erori \u00een platforma Mail.ru Cloud Solutions | ProHoster","description":".","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u043a\u0430\u0437\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u0430\u044f \u0432\u0435\u0431-\u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0432 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 Mail.ru Cloud Solutions | ProHoster","og:description":".","og:url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-11-06T21:00:00+00:00","article:modified_time":"2020-02-18T11:00:05+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"52389","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-24 03:27:21","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 20:44:43","updated":"2026-01-24 03:27:21","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/52389","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=52389"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/52389\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=52389"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=52389"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=52389"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}