{"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\/da\/blog\/administrirovanie\/kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions","title":{"rendered":"Hvordan realiseres en fejltolerant webarkitektur p\u00e5 Mail.ru Cloud Solutions-platformen?","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Hvordan realiseres en fejltolerant webarkitektur p\u00e5 Mail.ru Cloud Solutions-platformen?\" src=\"\/wp-content\/uploads\/2019\/11\/fe7af07f3ac5ca4e75009993b742293e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHej, Habr! Jeg er Artem Karamychev, leder af systemadministrationsteamet <noindex><a rel=\"nofollow\" href=\"https:\/\/mcs.mail.ru\/\">Mail.Ru Cloud Solutions (MCS)<\/a><\/noindex>. I l\u00f8bet af det sidste \u00e5r har vi lanceret mange nye produkter. Vi \u00f8nskede at sikre, at API-tjenester nemt kunne skaleres, var fejl tolerante og klar til hurtig v\u00e6kst i brugerbelastning. Vores platform er bygget p\u00e5 OpenStack, og jeg vil gerne fort\u00e6lle om de problemer med komponenternes fejl tolerans, som vi har m\u00e5ttet l\u00f8se for at opn\u00e5 et fejl tolerant system. Jeg tror, dette vil v\u00e6re interessant for dem, der ogs\u00e5 udvikler produkter p\u00e5 OpenStack.<\/p>\n<p>Den samlede fejl tolerans for platformen kommer fra robustheden af dens komponenter. S\u00e5 vi vil gradvist gennemg\u00e5 alle niveauer, hvor vi fandt risici og lukkede dem.<\/p>\n<p>Du kan se video versionen af denne historie, som stammer fra en pr\u00e6sentation p\u00e5 konferencen Uptime day 4, der blev organiseret af <noindex><a rel=\"nofollow\" href=\"http:\/\/www.itsumma.ru\">ITSumma<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=3b06MVou-vg&amp;list=PLmXjIrLllpkjwuIGkzBkLbI7oHtUadmvZ&amp;index=5\">p\u00e5 YouTube-kanalen Uptime Community<\/a><\/noindex>. <br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Fejl tolerans af den fysiske arkitektur<\/h2>\n<p>\nDen offentlige del af MCS-skyen er i \u00f8jeblikket baseret i to Tier III datacentre, der er forbundet med et eget m\u00f8rkt fiberkabelforbindelse, der er reserveret p\u00e5 det fysiske niveau med forskellige ruter, med en kapacitet p\u00e5 200 Gbit\/s. Tier III-niveauet sikrer det n\u00f8dvendige niveau af fejl tolerans i den fysiske infrastruktur. <\/p>\n<p>Det m\u00f8rke fiber er reserveret b\u00e5de p\u00e5 det fysiske og logiske niveau. Processen med at reservere kanaler var iterativ, der opstod problemer, og vi forbedrer konstant forbindelsen mellem datacentrerne. <\/p>\n<blockquote><p>For eksempel for nylig, under arbejde i en br\u00f8nd n\u00e6r et af datacentrene, blev r\u00f8r skadet med en gravemaskine, hvor b\u00e5de hoved- og backup optisk kabel var placeret. Vores fejl tolerante kommunikationskanal til datacentret viste sig at v\u00e6re s\u00e5rbar p\u00e5 \u00e9t punkt, i br\u00f8nden. Vi mistede s\u00e5ledes en del af infrastrukturen. Vi l\u00e6rte af det, tog en r\u00e6kke skridt, herunder at l\u00e6gge ekstra optik gennem den n\u00e6rliggende br\u00f8nd.<\/p><\/blockquote>\n<p>\nI datacentre findes der tilstedev\u00e6relsessteder for udbydere af netv\u00e6rk, som vi transmitterer vores pr\u00e6fikser til via BGP. For hver netv\u00e6rksretning v\u00e6lges den bedste metrik, hvilket muligg\u00f8r at levere den bedste forbindelseskvalitet til forskellige kunder. Hvis forbindelsen gennem en udbyder afbrydes, omdirigerer vi vores routing over de tilg\u00e6ngelige udbydere.<\/p>\n<p>Ved fejl i en udbyder skifter vi automatisk til den n\u00e6ste. Hvis en af datacentrene svigter, har vi en spejlet kopi af vores tjenester i det andet datacenter, som h\u00e5ndterer al belastning.<\/p>\n<p><img decoding=\"async\" alt=\"Hvordan realiseres en fejltolerant webarkitektur p\u00e5 Mail.ru Cloud Solutions-platformen?\" src=\"\/wp-content\/uploads\/2019\/11\/295ca212f48dd074d834154666e5b0c3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fejltolerance i den fysiske infrastruktur<\/i><\/p>\n<h2>Hvad vi bruger til fejltolerance p\u00e5 applikationsniveau<\/h2>\n<p>\nVores service er bygget p\u00e5 en r\u00e6kke opensource-komponenter. <\/p>\n<p><b>ExaBGP<\/b> \u2014 en service, der implementerer en r\u00e6kke funktioner ved hj\u00e6lp af en dynamisk routingprotokol baseret p\u00e5 BGP. Vi bruger det aktivt til at annoncere vores hvide IP-adresser, som brugerne f\u00e5r adgang til via API.<\/p>\n<p><b>HAProxy<\/b> \u2014 en h\u00f8jbelastet balancer, der muligg\u00f8r meget fleksible regler for trafikbalancering p\u00e5 forskellige niveauer af OSI-modellen. Vi bruger det til balancering foran alle tjenester: databaser, meddelelsesm\u00e6glere, API-tjenester, webtjenester, vores interne projekter - alt drives af HAProxy.<\/p>\n<p><b>API-applikation<\/b> \u2014 en webapplikation skrevet i python, hvormed brugeren styrer sin infrastruktur, sin service.<\/p>\n<p><b>Worker-applikation <\/b>(herefter blot worker) - i OpenStack-tjenester er dette en infrastrukturdaemon, der muligg\u00f8r transmission af API-kommandoer til infrastrukturen. For eksempel sker oprettelsen af en disk netop i worker, mens anmodningen om oprettelse sker i API-applikationen. <\/p>\n<h2>Standardarkitektur for OpenStack-applikation<\/h2>\n<p>\nDe fleste tjenester, der udvikles til OpenStack, fors\u00f8ger at f\u00f8lge en ensartet paradigme. En tjeneste best\u00e5r typisk af 2 dele: API og workers (backend-udf\u00f8rere). Som regel er API'et en WSGI-applikation skrevet i Python, der k\u00f8res enten som en selvst\u00e6ndig proces (daemon) eller via en eksisterende webserver som Nginx eller Apache. API'et behandler brugerens anmodning og videresender derefter instruktioner til worker-applikationen. Transmissionen foreg\u00e5r via en meddelelsesbroker, som typisk er RabbitMQ, mens andre varianter underst\u00f8ttes d\u00e5rligt. N\u00e5r beskederne kommer ind i brokeren, behandles de af workers, som om n\u00f8dvendigt returnerer et svar. <\/p>\n<p>Dette paradigme indeb\u00e6rer isolerede f\u00e6lles fejlpunkter: RabbitMQ og databasen. RabbitMQ er derimod isoleret inden for en enkelt tjeneste og kan i princippet v\u00e6re individuelt for hver service. Derfor adskiller vi i MCS maksimal disse tjenester; til hvert enkelt projekt opretter vi en separat database og en separat RabbitMQ. Denne tilgang er god, fordi i tilf\u00e6lde af en fejl p\u00e5 nogle s\u00e5rbare punkter, g\u00e5r ikke hele tjenesten ned, men kun en del af den.<\/p>\n<p>Antallet af worker-applikationer er ikke begr\u00e6nset af nogen faktorer, s\u00e5 API'et kan nemt skaleres horisontalt bag load-balancere for at \u00f8ge ydeevnen og fejltolerance.<\/p>\n<blockquote><p>I nogle tjenester er der behov for koordinering inden for tjenesten - n\u00e5r der udf\u00f8res komplekse sekventielle operationer mellem API'er og arbejdstagere. I dette tilf\u00e6lde anvendes et centralt koordinationspunkt, et klyngesystem som Redis, Memcache, etcd, der g\u00f8r det muligt for en arbejdstager at informere en anden om, at denne opgave er tildelt ham (\u00abdu, tag venligst ikke denne\u00bb). Vi bruger etcd. Generelt kommunikerer arbejdstagerne aktivt med databasen, skriver til og l\u00e6ser fra den. Som database bruger vi MariaDB, som vi har i et multimester-klynge.\n<\/p><\/blockquote>\n<p>\nDenne klassiske enkeltst\u00e5ende tjeneste er organiseret p\u00e5 den s\u00e6dvanlige m\u00e5de for OpenStack. Den kan betragtes som et lukket system, hvor metoderne til skalering og fejltolerance er rimeligt \u00e5benlyse. For eksempel er det tilstr\u00e6kkeligt at placere en load-balancer foran API'et for at sikre fejltolerance. Skaleringen af workers opn\u00e5s ved at \u00f8ge deres antal. <\/p>\n<p>Det svage punkt i hele systemet er RabbitMQ og MariaDB. Deres arkitektur fortjener en s\u00e6rskilt artikel. I denne artikel \u00f8nsker jeg at fokusere p\u00e5 API'ernes fejlfindingsfrihed.<\/p>\n<p><img decoding=\"async\" alt=\"Hvordan realiseres en fejltolerant webarkitektur p\u00e5 Mail.ru Cloud Solutions-platformen?\" src=\"\/wp-content\/uploads\/2019\/11\/f39e5a8ae350864e311bf4db3b9c34b3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Arkitektur for Openstack Application. Belastningsfordeling og fejltolerance for cloud-platformen<\/i><\/p>\n<h2>G\u00f8r HAProxy-belastningsfordeleren fejltolerant med ExaBGP<\/h2>\n<p>\nFor at vores API'er kan v\u00e6re skalerbare, hurtige og fejltolerante, har vi placeret en belastningsfordeler foran dem. Vi valgte HAProxy. Efter min mening har det alle de n\u00f8dvendige egenskaber til vores opgave: belastning p\u00e5 flere OSI-niveauer, administrationsinterface, fleksibilitet og skalerbarhed, et stort antal belastningsmetoder, underst\u00f8ttelse af sessionstabeller.<\/p>\n<p>Det f\u00f8rste problem, der skulle l\u00f8ses, var fejltolerance for selve belastningsfordeleren. Bare at installere belastningsfordeleren skaber ogs\u00e5 et fejlpunk: hvis belastningsfordeleren g\u00e5r ned, falder tjenesten. For at undg\u00e5 dette brugte vi HAProxy sammen med ExaBGP.<\/p>\n<p>ExaBGP muligg\u00f8r implementeringen af en mekanisme til sundhedstjek af tjenesten. Vi brugte denne mekanisme til at kontrollere HAProxy's funktionalitet og i tilf\u00e6lde af problemer slukke HAProxy-tjenesten fra BGP. <\/p>\n<p><b>Diagram over ExaBGP+HAProxy<\/b><\/p>\n<ol>\n<li>Vi installerer den n\u00f8dvendige software, ExaBGP og HAProxy, p\u00e5 tre servere. <\/li>\n<li>P\u00e5 hver af serverne opretter vi en loopback-gr\u00e6nseflade.<\/li>\n<li>P\u00e5 alle tre servere angiver vi den samme offentlige IP-adresse for denne gr\u00e6nseflade.<\/li>\n<li>Den offentlige IP-adresse annonceres til internettet via ExaBGP. <\/li>\n<\/ol>\n<p>\nFejltolerance opn\u00e5s ved at annoncere den samme IP-adresse fra alle tre servere. Set fra netv\u00e6rket er den samme adresse tilg\u00e6ngelig fra tre forskellige next-hop. Routeren ser tre identiske ruter og v\u00e6lger den mest prioriterede baseret p\u00e5 sin egen metrik (som normalt er den samme), og trafikken g\u00e5r kun til \u00e9n af serverne. <\/p>\n<p>I tilf\u00e6lde af problemer med HAProxy eller hvis en server g\u00e5r ned, stopper ExaBGP med at annoncere ruten, og trafikken skifter glidende til en anden server. <\/p>\n<p>Dermed har vi opn\u00e5et fejltolerance for belastningsfordeleren.<\/p>\n<p><img decoding=\"async\" alt=\"Hvordan realiseres en fejltolerant webarkitektur p\u00e5 Mail.ru Cloud Solutions-platformen?\" src=\"\/wp-content\/uploads\/2019\/11\/9fba0718176dc1266f25a2c01ec87348.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fejltolerance for HAProxy-belastningsfordelere<\/i><\/p>\n<p>Skemaet er ikke perfekt: vi har l\u00e6rt at redundere HAProxy, men ikke at fordele belastningen inden for tjenesterne. Derfor har vi udvidet denne skema lidt: vi er g\u00e5et over til belastningsfordeling mellem flere offentlige IP-adresser.<\/p>\n<h2>DNS-baseret belastningsbalance plus BGP<\/h2>\n<p>\nSp\u00f8rgsm\u00e5let om belastningsbalance foran vores HAProxy er stadig ikke l\u00f8st. Men det kan l\u00f8ses ret enkelt, som vi gjorde det hos os.<\/p>\n<p>Til belastningsbalancering af tre servere vil der v\u00e6re brug for 3 offentlige IP-adresser og den gode gamle DNS. Hver af disse adresser defineres p\u00e5 loopback-gr\u00e6nsefladen for hver HAProxy og annonceres p\u00e5 internettet. <\/p>\n<p>I OpenStack bruges en servicekatalog til at styre ressourcer, hvor endpoint API for enhver given service angives. I dette katalog angiver vi dom\u00e6nenavnet \u2014 public.infra.mail.ru, som opl\u00f8ses via DNS til tre forskellige IP-adresser. Resultatet er, at vi opn\u00e5r belastningsfordeling mellem de tre adresser via DNS. <\/p>\n<p>Men da vi ikke styrer prioriteterne for valg af server ved annoncering af de offentlige IP-adresser, er det ikke rigtig belastningsbalance. Som regel vil kun \u00e9n server blive valgt based p\u00e5 IP-adressens anciennitet, mens de to andre forbliver inaktive, da der ikke er angivet nogen m\u00e5linger i BGP.<\/p>\n<p>Vi begyndte at annoncere ruter gennem ExaBGP med forskellige m\u00e5linger. Hver belastningsbalancer annoncerer alle tre offentlige IP-adresser, men en af dem, den hovedadresse for denne belastningsbalancer, annonceres med den laveste m\u00e5ling. S\u00e5 l\u00e6nge alle tre belastningsbalancere er i drift, sendes anmodninger til den f\u00f8rste IP-adresse til den f\u00f8rste belastningsbalancer, anmodninger til den anden til den anden, og til den tredje til den tredje.<\/p>\n<p>Hvad sker der i det \u00f8jeblik, en af belastningsbalancerne falder ud? Ved nedbrud af en hvilken som helst belastningsbalancer annonceres dens grundl\u00e6ggende adresse stadig fra de to andre, og trafikken omfordeles mellem dem. Dermed giver vi brugeren flere IP-adresser gennem DNS. Gennem DNS-belastningsbalancering og forskellige m\u00e5linger opn\u00e5r vi en j\u00e6vn fordeling af belastningen p\u00e5 alle tre belastningsbalancere. Og samtidig mister vi ikke fejltolerance.<\/p>\n<p><img decoding=\"async\" alt=\"Hvordan realiseres en fejltolerant webarkitektur p\u00e5 Mail.ru Cloud Solutions-platformen?\" src=\"\/wp-content\/uploads\/2019\/11\/1485367a934aea06b68c6d05c184d263.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>HAProxy-belastningsbalance baseret p\u00e5 DNS + BGP<\/i><\/p>\n<h2>Interaktion mellem ExaBGP og HAProxy<\/h2>\n<p>\nS\u00e5 vi har implementeret fejltolerance i tilf\u00e6lde af serversvigt baseret p\u00e5 oph\u00f8r af ruteannoncering. Men HAProxy kan ogs\u00e5 g\u00e5 ned af andre \u00e5rsager end serverfejl: administrationsfejl, fejl i tjenesten. Vi \u00f8nsker at fjerne den defekte belastningsbalancer fra belastningen i disse tilf\u00e6lde, og der er behov for en anden mekanisme. <\/p>\n<p>Derfor, ved at udvide det tidligere skema, har vi implementeret heartbeat mellem ExaBGP og HAProxy. Dette er en softwareimplementering af interaktionen mellem ExaBGP og HAProxy, hvor ExaBGP bruger tilpassede scripts til at kontrollere status for applikationer.<\/p>\n<p>For dette skal health checker konfigureres i ExaBGP, s\u00e5 den kan kontrollere status p\u00e5 HAProxy. I vores tilf\u00e6lde har vi konfigureret health backend i HAProxy, og fra ExaBGP tjekker vi med en simpel GET-anmodning. Hvis annonceringen stopper, fungerer HAProxy sandsynligvis ikke, og den skal ikke annonceres. <\/p>\n<p><img decoding=\"async\" alt=\"Hvordan realiseres en fejltolerant webarkitektur p\u00e5 Mail.ru Cloud Solutions-platformen?\" src=\"\/wp-content\/uploads\/2019\/11\/d5cda30043fe02ab81355b28c0d83ac6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>HAProxy Health Check<\/i><\/p>\n<h2>HAProxy Peers: session synchronisering <\/h2>\n<p>\nDet n\u00e6ste, vi skulle g\u00f8re, var at synkronisere sessioner. N\u00e5r man arbejder med distribuerede belastningsbalancere, er det vanskeligt at organisere gemmelse af information om kunders sessioner. Men HAProxy er en af de f\u00e5 balancere, der kan dette takket v\u00e6re Peers-funktionen \u2014 muligheden for at overf\u00f8re sessionstabeller mellem forskellige HAProxy-processer. <\/p>\n<p>Der findes forskellige metoder til belastningsbalancering: simple, s\u00e5som <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)\">rundt-rundt<\/a><\/noindex>, og avancerede, hvor kundens session huskes, og han hver gang lander p\u00e5 den samme server som f\u00f8r. Vi ville implementere den anden variant.<\/p>\n<p>I HAProxy bruges stick-tables til at gemme kundens sessioner. De gemmer den oprindelige kunde-IP, den valgte target-adresse (backend) og nogle tjenesteinformationer. Som regel bruges stick-tabeller til at gemme parrene source-IP + destination-IP, hvilket er s\u00e6rligt nyttigt for applikationer, der ikke kan overf\u00f8re brugerens sessionens kontekst ved skift til en anden belastningsbalancer, eksempelvis i RoundRobin-belastningsbalanceringsmodus.<\/p>\n<p>Hvis stick-tabellen kan l\u00e6re at flytte sig mellem forskellige HAProxy-processer (imellem hvilke belastningsbalanceringen foreg\u00e5r), vil vores balancere kunne arbejde med en f\u00e6lles pulje af stick-tabeller. Dette vil muligg\u00f8re s\u00f8ml\u00f8s skift af kundens netv\u00e6rk, hvis en af balancerne fejler, og arbejdet med kundesessioner vil forts\u00e6tte p\u00e5 de samme backends, som blev valgt tidligere.<\/p>\n<p>For korrekt funktion skal problemet med IP-adressen p\u00e5 den belastningsbalancer, hvor sessionen er etableret, l\u00f8ses. I vores tilf\u00e6lde er dette en dynamisk adresse p\u00e5 loopback-interfacet. <\/p>\n<p>Korrekt drift af peers opn\u00e5s kun under bestemte betingelser. Det vil sige, at TCP-timeouts skal v\u00e6re tilstr\u00e6kkeligt store, eller skiftet skal v\u00e6re hurtigt nok til, at TCP-sessionen ikke n\u00e5r at afbryde. Dette muligg\u00f8r dog problemfrit at skifte. <\/p>\n<p>Vi har en tjeneste i IaaS, der er bygget med samme teknologi. Det er <noindex><a rel=\"nofollow\" href=\"https:\/\/mcs.mail.ru\/app\/services\/infra\/balancers-list\/\">Load Balancer som en tjeneste til OpenStack<\/a><\/noindex>, som kaldes Octavia. Den er baseret p\u00e5 to HAProxy-processer, og der er oprindeligt indbygget st\u00f8tte til peers. I denne tjeneste har de vist sig at fungere fremragende.<\/p>\n<p>P\u00e5 billedet er der skematisk vist bev\u00e6gelsen af peers-tabeller mellem tre instanser af HAProxy, og et forslag til konfiguration, hvordan dette kan indstilles:<\/p>\n<p><img decoding=\"async\" alt=\"Hvordan realiseres en fejltolerant webarkitektur p\u00e5 Mail.ru Cloud Solutions-platformen?\" src=\"\/wp-content\/uploads\/2019\/11\/d31fab761da627923345b7ace7f0b943.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>HAProxy Peers (session synkronisering)<\/i><\/p>\n<p>Hvis du vil implementere en lignende ordning, skal du n\u00f8je teste dens funktion. Det er ikke sikkert, at det vil fungere p\u00e5 samme m\u00e5de i 100% af tilf\u00e6ldene. Men i det mindste vil du ikke miste stick-tabeller, n\u00e5r du skal huske kilde-IP'en fra klienten.<\/p>\n<h2>Begr\u00e6nsning af antallet af samtidige foresp\u00f8rgsler fra den samme klient<\/h2>\n<p>\nEnhver tjeneste, der er offentligt tilg\u00e6ngelig, herunder vores API'er, kan v\u00e6re udsat for b\u00f8lger af foresp\u00f8rgsler. \u00c5rsagerne kan v\u00e6re vidt forskellige, fra brugerfejl til m\u00e5lrettede angreb. Vi oplever j\u00e6vnligt DDoS-angreb via IP-adresser. Kunderne laver ofte fejl i deres scripts og uds\u00e6tter os for mini-DDoS-angreb.<\/p>\n<p>P\u00e5 den ene eller den anden m\u00e5de er det n\u00f8dvendigt at forudse en ekstra beskyttelse. En \u00e5benlys l\u00f8sning er at begr\u00e6nse antallet af anmodninger til API'et og ikke spilde processorens tid p\u00e5 at behandle skadelige foresp\u00f8rgsler.<\/p>\n<p>Til at implementere s\u00e5danne begr\u00e6nsninger anvender vi rate limits, organiseret p\u00e5 basis af HAProxy, ved hj\u00e6lp af de samme stick-tabeller. Begr\u00e6nsningerne kan indstilles ret enkelt og tillader at begr\u00e6nse brugeren i antallet af anmodninger til API'et. Algoritmen husker kilde-IP'en, hvorfra der foretages foresp\u00f8rgsler, og begr\u00e6nser antallet af samtidige anmodninger fra \u00e9n bruger. Selvf\u00f8lgelig har vi beregnet den gennemsnitlige belastningsprofil p\u00e5 API'et for hver tjeneste og etableret en gr\u00e6nse, der er ca. 10 gange st\u00f8rre end denne v\u00e6rdi. Vi forts\u00e6tter med at overv\u00e5ge situationen n\u00f8je og holder h\u00e5nden p\u00e5 pulsen.<\/p>\n<p>Hvordan ser det ud i praksis? Vi har kunder, der konstant bruger vores API til automatisk skalering. De opretter cirka to hundrede til tre hundrede virtuelle maskiner t\u00e6ttere p\u00e5 morgen og sletter dem t\u00e6ttere p\u00e5 aften. For OpenStack at oprette en virtuel maskine, is\u00e6r med PaaS-tjenester, kr\u00e6ver det mindst 1000 API-anmodninger, da interaktionen mellem tjenesterne ogs\u00e5 sker gennem API. <\/p>\n<p>S\u00e5dan omfordeling af opgaver medf\u00f8rer en betydelig belastning. Vi har vurderet denne belastning, indsamlet daglige toppe, fordoblet dem, og dette blev vores rate-limit. Vi holder styr p\u00e5 situationen. Vi ser ofte bots og scannere, som fors\u00f8ger at unders\u00f8ge os for at se, om vi har nogle CGA-scripts, som de kan k\u00f8re; vi sk\u00e6rer aktivt ned p\u00e5 dem.<\/p>\n<h2>Hvordan man opdaterer kodebasen uset for brugerne<\/h2>\n<p>\nVi implementerer ogs\u00e5 fejltolerance p\u00e5 niveau med kodeudrulningsprocesser. Under udrulninger opst\u00e5r der fejl, men deres indflydelse p\u00e5 serviceadgang kan minimeres.<\/p>\n<p>Vi opdaterer konstant vores tjenester og skal sikre, at opdateringsprocessen for kodebasen ikke p\u00e5virker brugerne. Vi har l\u00f8st denne opgave ved at bruge mulighederne for styring af HAProxy og implementering af Graceful Shutdown i vores tjenester.<\/p>\n<p>For at l\u00f8se denne opgave var det n\u00f8dvendigt at sikre styring af load-balanceren og en \"proper\" nedlukning af tjenesterne:<\/p>\n<ul>\n<li>I tilf\u00e6lde af HAProxy sker styring gennem stats-filen, der i bund og grund er en socket og defineres i konfigurationen af HAProxy. Kommandoer kan sendes dertil gennem stdio. Men vores prim\u00e6re v\u00e6rkt\u00f8j til kontrol af konfigurationer er Ansible, s\u00e5 der er en indbygget modul til styring af HAProxy, som vi bruger aktivt. <\/li>\n<li>St\u00f8rstedelen af vores API- og Engine-tjenester underst\u00f8tter teknologier til en blid nedlukning: ved nedlukning venter de p\u00e5, at den aktuelle opgave er fuldf\u00f8rt, uanset om det er en http-anmodning eller en tjenesteopgave. Det samme g\u00e6lder arbejdstagerne. De kender alle de opgaver, de udf\u00f8rer, og afslutter, n\u00e5r de har afsluttet alt med succes. <\/li>\n<\/ul>\n<p>\nTakket v\u00e6re disse to punkter ser vores sikre udrulningsalgoritme s\u00e5dan ud.<\/p>\n<ol>\n<li>Udvikleren samler en ny kodepakke (for os er dette RPM), tester den i udviklingsmilj\u00f8et, tester den i staging, og efterlader den i staging-repositoriet.<\/li>\n<li>Udvikleren angiver opgaven med deployment med en s\u00e5 detaljeret beskrivelse af \"artefakterne\" som muligt: versionen af den nye pakke, beskrivelsen af den nye funktionalitet og andre detaljer om deploymentet, hvis n\u00f8dvendigt.<\/li>\n<li>Systemadministratoren p\u00e5begynder opdateringen. Han starter Ansible-playbook'en, som g\u00f8r f\u00f8lgende: \n<ul>\n<li>Henter pakken fra stage-repositoriet og opdaterer pakken i produktionsrepositoriet.<\/li>\n<li>Sammens\u00e6tter listen over backends for den opdaterede service.<\/li>\n<li>Slukker for den f\u00f8rste opdaterede service i HAProxy og venter p\u00e5, at dens processer er f\u00e6rdige. Takket v\u00e6re graceful shutdown er vi sikre p\u00e5, at alle eksisterende kundeanmodninger vil blive afsluttet succesfuldt.<\/li>\n<li>Efter en fuldst\u00e6ndig stop af API'et, arbejdstagerne, og nedlukning af HAProxy, sker der en kodeopdatering.<\/li>\n<li>Ansible starter tjenesterne.<\/li>\n<li>For hver tjeneste kalder den specifikke \"knapper\", der udf\u00f8rer unit-testning baseret p\u00e5 en r\u00e6kke foruddefinerede testn\u00f8gler. Der udf\u00f8res en grundl\u00e6ggende kontrol af den nye kode.<\/li>\n<li>Hvis der ikke blev opdaget fejl i det forrige trin, aktiveres backend'en.<\/li>\n<li>Vi g\u00e5r videre til den n\u00e6ste backend.<\/li>\n<\/ul>\n<\/li>\n<li>Efter opdateringen af alle backends, startes funktionelle tests. Hvis der mangler tests, ser udvikleren p\u00e5 enhver ny funktionalitet, han har arbejdet p\u00e5.<\/li>\n<\/ol>\n<p>\nDeploymentet er nu f\u00e6rdigt.<\/p>\n<p><img decoding=\"async\" alt=\"Hvordan realiseres en fejltolerant webarkitektur p\u00e5 Mail.ru Cloud Solutions-platformen?\" src=\"\/wp-content\/uploads\/2019\/11\/2d889fe1af33653e4bfebabe1cce6552.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Cyklen for at opdatere servicen<\/i><\/p>\n<p>Denne skema ville ikke fungere, hvis vi ikke havde \u00e9n regel. Vi underst\u00f8tter samtidig b\u00e5de den gamle og den nye version i produktion. P\u00e5 forh\u00e5nd, i softwareudviklingsfasen, tages det i betragtning, at selvom der sker \u00e6ndringer i databasen for tjenesten, vil de ikke bryde den tidligere kode. Resultatet er en gradvis opdatering af kodebasen.<\/p>\n<h2>Konklusion<\/h2>\n<p>\nN\u00e5r jeg deler mine tanker om fejltolerant WEB-arkitektur, vil jeg endnu en gang understrege dens n\u00f8glepunkter:<\/p>\n<ul>\n<li>fysisk fejltolerance;<\/li>\n<li>netv\u00e6rksfejltolerance (load balancere, BGP);<\/li>\n<li>fejltolerance af den anvendte og udviklede software.<\/li>\n<\/ul>\n<p>\nAlle \u00f8nsker stabil uptime!<br \/>\n<br \/>Kilde: <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.3 - 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\/da\/blog\/administrirovanie\/kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\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\/da\/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\udd47Hvordan implementeres fejltolerant web-arkitektur i Mail.ru Cloud Solutions platformen | ProHoster","description":".","canonical_url":"https:\/\/prohoster.info\/da\/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":"da_DK","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\/da\/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\/da\/wp-json\/wp\/v2\/posts\/52389","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=52389"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/52389\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=52389"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=52389"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=52389"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}