{"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\/nl\/blog\/administrirovanie\/kak-realizuetsya-otkazoustojchivaya-veb-arhitektura-v-platforme-mail-ru-cloud-solutions","title":{"rendered":"Hoe wordt een failover-webarchitectuur gerealiseerd in het Mail.ru Cloud Solutions-platform","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Hoe wordt een failover-webarchitectuur gerealiseerd in het Mail.ru Cloud Solutions-platform\" src=\"\/wp-content\/uploads\/2019\/11\/fe7af07f3ac5ca4e75009993b742293e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHallo, Habr! Ik ben Artem Karashchev, teamleider van systeembeheer. <noindex><a rel=\"nofollow\" href=\"https:\/\/mcs.mail.ru\/\">Mail.Ru Cloud Solutions (MCS)<\/a><\/noindex>. Het afgelopen jaar hadden we veel nieuwe productlanceringen. We wilden dat API-services gemakkelijk schaalbaar, fouttolerant en voorbereid waren op snelle groei van het gebruikersverkeer. Ons platform is gebouwd op OpenStack, en ik wil vertellen over de probleemstukken rondom de fouttolerantie van componenten die we moesten aanpakken om een fouttolerant systeem te krijgen. Ik denk dat dit interessant zal zijn voor degenen die ook producten ontwikkelen op OpenStack.<\/p>\n<p>De algehele fouttolerantie van het platform is opgebouwd uit de weerbaarheid van zijn componenten. Dus we zullen geleidelijk alle niveaus doorlopen waarop we risico's hebben ontdekt en deze hebben aangepakt.<\/p>\n<p>De videoversie van dit verhaal, dat oorspronkelijk afkomstig is uit een presentatie op de Uptime day 4-conferentie georganiseerd door <noindex><a rel=\"nofollow\" href=\"http:\/\/www.itsumma.ru\">ITSumma<\/a><\/noindex>, kan worden bekeken <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=3b06MVou-vg&amp;list=PLmXjIrLllpkjwuIGkzBkLbI7oHtUadmvZ&amp;index=5\">op het YouTube-kanaal van Uptime Community.<\/a><\/noindex>. <br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Fouttolerantie van de fysieke architectuur<\/h2>\n<p>\nHet openbare deel van de MCS-cloud is nu gebaseerd in twee datacenters van Tier III-niveau, die met elkaar zijn verbonden via eigen donkere vezels, gereserveerd op fysiek niveau door verschillende routes, met een bandbreedte van 200 Gbit\/s. Tier III-niveau biedt het vereiste niveau van fouttolerantie voor de fysieke infrastructuur. <\/p>\n<p>Donkere vezels zijn gereserveerd op zowel fysiek als logisch niveau. Het proces van het reserveren van verbindingen was iteratief, er deden zich problemen voor en we blijven de verbinding tussen de datacenters voortdurend verbeteren. <\/p>\n<blockquote><p>Bijvoorbeeld, niet zo lang geleden, tijdens werkzaamheden in een put nabij een van de datacenters, heeft een graafmachine een buis doorboord, waarin zowel de primaire als de secundaire optische kabel zich bevonden. Onze fouttolerante verbinding met het datacenter bleek op \u00e9\u00e9n punt in de put kwetsbaar te zijn. Daardoor hebben we een deel van de infrastructuur verloren. We hebben lessen getrokken, een aantal maatregelen genomen, waaronder het leggen van extra glasvezelkabels in de aangrenzende put.<\/p><\/blockquote>\n<p>\nIn datacenters zijn er punten van aanwezigheid van telecomproviders, aan wie we onze prefixen via BGP doorgeven. Voor elke netwerkrichting wordt de beste metriek gekozen, wat het mogelijk maakt om verschillende klanten de beste verbindingskwaliteit te bieden. Als de verbinding via \u00e9\u00e9n provider uitvalt, passen we onze routering aan via beschikbare providers.<\/p>\n<p>Bij een storing van de provider schakelen we automatisch over naar de volgende. In het geval van een storing in een van de datacenters hebben we een spiegelkopie van onze diensten in het tweede datacenter, dat de volledige belasting op zich neemt.<\/p>\n<p><img decoding=\"async\" alt=\"Hoe wordt een failover-webarchitectuur gerealiseerd in het Mail.ru Cloud Solutions-platform\" src=\"\/wp-content\/uploads\/2019\/11\/295ca212f48dd074d834154666e5b0c3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Hogere beschikbaarheid van de fysieke infrastructuur<\/i><\/p>\n<h2>Wat we gebruiken voor hogere beschikbaarheid op applicatieniveau<\/h2>\n<p>\nOnze service is opgebouwd uit een aantal open source-componenten. <\/p>\n<p><b>ExaBGP<\/b> \u2014 een service die een aantal functies implementeert met behulp van een protocol voor dynamische routering op basis van BGP. We gebruiken het actief om onze witte IP-adressen aan te kondigen, waardoor gebruikers toegang krijgen tot de API.<\/p>\n<p><b>HAProxy<\/b> \u2014 een hoogbelastbare load balancer die zeer flexibele verkeersbalanceringsregels op verschillende niveaus van het OSI-model mogelijk maakt. We gebruiken het voor de balanceringsfunctie voor al onze services: databases, message brokers, API-services, web-services, onze interne projecten \u2014 alles draait achter HAProxy.<\/p>\n<p><b>API-toepassing<\/b> \u2014 een webtoepassing, geschreven in Python, waarmee de gebruiker zijn infrastructuur en services beheert.<\/p>\n<p><b>Worker-toepassing <\/b>(hierna gewoon worker) \u2014 in OpenStack-services is dit een infrastructuurdaemon die API-commando's naar de infrastructuur vertaalt. Bijvoorbeeld, de creatie van een schijf gebeurt daadwerkelijk in de worker, terwijl het verzoek om creatie plaatsvindt in de API-toepassing. <\/p>\n<h2>Standaardarchitectuur van OpenStack-toepassing<\/h2>\n<p>\nDe meeste diensten die voor OpenStack worden ontwikkeld, proberen een uniforme paradigma te volgen. Een service bestaat doorgaans uit twee delen: API en workers (achtergrondprocessen). De API is meestal een WSGI-toepassing in Python, die wordt uitgevoerd als een zelfstandige proces (daemon) of met behulp van een kant-en-klaar webserver zoals Nginx of Apache. De API verwerkt de gebruikersaanvragen en geeft verdere instructies door aan de worker-toepassing. Deze overdracht gebeurt via een berichtenbroker, meestal RabbitMQ, de andere worden slecht ondersteund. Wanneer berichten de broker bereiken, worden ze door de workers verwerkt en, indien nodig, antwoorden teruggestuurd. <\/p>\n<p>Dit paradigma impliceert ge\u00efsoleerde gemeenschappelijke faalpunten: RabbitMQ en de database. RabbitMQ is echter ge\u00efsoleerd binnen een enkele service en kan in principe voor elke service afzonderlijk zijn. Daarom splitsen we bij MCS deze services zoveel mogelijk; voor elk afzonderlijk project cre\u00ebren we een aparte database en een aparte RabbitMQ. Deze aanpak is gunstig omdat in geval van een storing in kwetsbare punten niet de gehele service faalt, maar alleen een deel ervan.<\/p>\n<p>Het aantal worker-toepassingen is onbeperkt, waardoor de API gemakkelijk horizontaal kan worden geschaald achter load balancers, wat de prestaties en de fouttolerantie verhoogt.<\/p>\n<blockquote><p>In sommige diensten is co\u00f6rdinatie binnen de service noodzakelijk \u2014 wanneer er complexe opeenvolgende bewerkingen plaatsvinden tussen API's en workers. In dit geval wordt een centraal co\u00f6rdinatiepunt gebruikt, een clustersysteem zoals Redis, Memcache, of etcd, dat het mogelijk maakt voor \u00e9\u00e9n worker om tegen een andere te zeggen dat deze taak aan hem is toegewezen (\"jij hoeft deze niet op te pakken\"). Wij gebruiken etcd. Gewoonlijk communiceren workers actief met de database, waarbij ze informatie schrijven en lezen. Voor de database gebruiken we MariaDB, die zich in een multimaster-cluster bevindt.\n<\/p><\/blockquote>\n<p>\nEen klassieke enkele service is georganiseerd op de gebruikelijke manier voor OpenStack. Het kan worden beschouwd als een afgesloten systeem, waarvan de manieren voor schaalvergroting en fouttolerantie vrij duidelijk zijn. Bijvoorbeeld, voor fouttolerantie is het voldoende om een load balancer voor de API te plaatsen. De schaalvergroting van workers wordt bereikt door hun aantal te verhogen. <\/p>\n<p>Het zwakke punt in het hele systeem zijn RabbitMQ en MariaDB. Hun architectuur verdient een apart artikel. In dit artikel wil ik me richten op de fault-tolerantie van de API.<\/p>\n<p><img decoding=\"async\" alt=\"Hoe wordt een failover-webarchitectuur gerealiseerd in het Mail.ru Cloud Solutions-platform\" src=\"\/wp-content\/uploads\/2019\/11\/f39e5a8ae350864e311bf4db3b9c34b3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Openstack Application Architectuur. Balanceren en fault-tolerantie van het cloudplatform.<\/i><\/p>\n<h2>We maken de HAProxy load balancer fault-tolerant met behulp van ExaBGP.<\/h2>\n<p>\nOm onze API's schaalbaar, snel en fault-tolerant te maken, hebben we een load balancer voor hen geplaatst. We kozen voor HAProxy. Naar mijn mening heeft het alle noodzakelijke eigenschappen voor onze taak: balancering op meerdere OSI-niveaus, een beheerdersinterface, flexibiliteit en schaalbaarheid, een groot aantal balanceringsmethoden en ondersteuning voor sessietabellen.<\/p>\n<p>Het eerste probleem dat moest worden opgelost, was de fault-tolerantie van de load balancer zelf. Gewoon het installeren van een load balancer cre\u00ebert ook een enkel punt van falen: als de load balancer uitvalt, valt de service uit. Om dit te voorkomen, gebruikten we HAProxy samen met ExaBGP.<\/p>\n<p>ExaBGP maakt het mogelijk om een mechanism voor service statuscontrole te implementeren. We gebruikten dit mechanisme om de werking van HAProxy te controleren en in geval van problemen de HAProxy-service uit te schakelen vanuit BGP. <\/p>\n<p><b>Schema ExaBGP+HAProxy<\/b><\/p>\n<ol>\n<li>We installeren de benodigde software, ExaBGP en HAProxy, op drie servers. <\/li>\n<li>Op elke server cre\u00ebren we een loopback-interface.<\/li>\n<li>Op alle drie de servers configureren we dezelfde publieke IP-adres voor deze interface.<\/li>\n<li>Het publieke IP-adres wordt op internet geannonceerd via ExaBGP. <\/li>\n<\/ol>\n<p>\nFault-tolerantie wordt bereikt door hetzelfde IP-adres vanaf alle drie de servers aan te kondigen. Vanuit het netwerk gezien is hetzelfde adres beschikbaar via drie verschillende next hops. De router ziet drie identieke routes en kiest op basis van zijn eigen metric de meest prioritaire (dit is meestal dezelfde optie), en het verkeer gaat alleen naar een van de servers. <\/p>\n<p>Bij problemen met de werking van HAProxy of de uitval van een server, stopt ExaBGP met het aankondigen van de route en schakelt het verkeer soepel over naar een andere server. <\/p>\n<p>Op deze manier hebben we fault-tolerantie voor de load balancer bereikt.<\/p>\n<p><img decoding=\"async\" alt=\"Hoe wordt een failover-webarchitectuur gerealiseerd in het Mail.ru Cloud Solutions-platform\" src=\"\/wp-content\/uploads\/2019\/11\/9fba0718176dc1266f25a2c01ec87348.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Fault-tolerantie van HAProxy load balancers.<\/i><\/p>\n<p>Het schema is niet ideaal: we hebben geleerd om HAProxy te redunderen, maar we hebben niet geleerd om de belasting binnen de services te verdelen. Daarom hebben we dit schema iets uitgebreid: we zijn overgestapt op balanceren tussen meerdere publieke IP-adressen.<\/p>\n<h2>DNS-gebaseerde load balancing plus BGP<\/h2>\n<p>\nDe kwestie van load balancing voor onze HAProxy is nog niet opgelost. Het kan echter vrij eenvoudig worden opgelost, zoals wij dat ook hebben gedaan.<\/p>\n<p>Voor de load balancing van drie servers zijn 3 publieke IP-adressen en de goede oude DNS nodig. Elk van deze adressen wordt toegewezen aan de loopback-interface van elke HAProxy en wordt op internet geannonceerd. <\/p>\n<p>In OpenStack wordt een service catalogus gebruikt voor het beheer van middelen, waarin de API-endpoint van elke service wordt gedefinieerd. In deze catalogus vermelden we de domeinnaam \u2014 public.infra.mail.ru, die via DNS wordt geresolleerd naar drie verschillende IP-adressen. Hierdoor krijgen we een load balancing tussen de drie adressen via DNS. <\/p>\n<p>Maar omdat we bij het adverteren van publieke IP-adressen de prioriteiten voor de serverkeuze niet beheren, is dit nog geen load balancing. Gewoonlijk wordt slechts \u00e9\u00e9n server gekozen op basis van de senioriteit van het IP-adres, terwijl de andere twee inactief blijven, omdat er geen metrics in BGP zijn opgegeven.<\/p>\n<p>We zijn begonnen met het adverteren van routes via ExaBGP met verschillende metrics. Elke load balancer annonceert alle drie de publieke IP-adressen, maar \u00e9\u00e9n ervan, de belangrijkste voor deze load balancer, wordt aangekondigd met de laagste metric. Dus zolang alle drie de load balancers operationeel zijn, komen verzoeken naar het eerste IP-adres terecht bij de eerste load balancer, verzoeken naar het tweede bij de tweede, en naar het derde bij de derde.<\/p>\n<p>Wat gebeurt er op het moment dat een van de load balancers uitvalt? Bij het falen van een load balancer wordt het basisadres nog steeds geannonceerd door de twee andere, waardoor het verkeer tussen hen wordt herverdeeld. Op deze manier bieden we de gebruiker via DNS meerdere IP-adressen tegelijk aan. Door load balancing via DNS en verschillende metrics krijgen we een uniforme verdeling van de belasting over de drie load balancers en behouden we tegelijkertijd de fouttolerantie.<\/p>\n<p><img decoding=\"async\" alt=\"Hoe wordt een failover-webarchitectuur gerealiseerd in het Mail.ru Cloud Solutions-platform\" src=\"\/wp-content\/uploads\/2019\/11\/1485367a934aea06b68c6d05c184d263.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>HAProxy load balancing gebaseerd op DNS + BGP<\/i><\/p>\n<h2>Interactie tussen ExaBGP en HAProxy<\/h2>\n<p>\nDus we hebben fouttolerantie ge\u00efmplementeerd voor het geval een server uitvalt, op basis van het stoppen met het adverteren van routes. Maar HAProxy kan om andere redenen uitvallen dan een server die defect raakt: beheersfouten, storingen binnen de service. We willen de defecte load balancer uit de belasting halen, zelfs in deze gevallen, en daar hebben we een ander mechanisme voor nodig. <\/p>\n<p>Daarom hebben we, door de vorige opzet uit te breiden, een heartbeat tussen ExaBGP en HAProxy ge\u00efmplementeerd. Dit is een software-implementatie van de interactie tussen ExaBGP en HAProxy, waarbij ExaBGP aangepaste scripts gebruikt om de status van applicaties te controleren.<\/p>\n<p>Hiervoor moet in de ExaBGP-configuratie een health checker worden ingesteld die de status van HAProxy kan controleren. In ons geval hebben we een health backend in HAProxy ingesteld, en aan de kant van ExaBGP controleren we dit met een eenvoudige GET-aanroep. Als de aankondiging stopt, betekent dit dat HAProxy waarschijnlijk niet werkt en dat het niet nodig is om deze aan te kondigen. <\/p>\n<p><img decoding=\"async\" alt=\"Hoe wordt een failover-webarchitectuur gerealiseerd in het Mail.ru Cloud Solutions-platform\" 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: sessie-synchronisatie <\/h2>\n<p>\nHet volgende wat moest gebeuren, was het synchroniseren van sessies. Het is moeilijk om informatie over klantensessies op te slaan bij het gebruik van gedistribueerde load balancers. Maar HAProxy is een van de weinige load balancers die dit kan dankzij de Peers-functie, waarmee sessietabellen tussen verschillende HAProxy-processen kunnen worden doorgegeven. <\/p>\n<p>Er zijn verschillende balanceringsmethoden: eenvoudige, zoals <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)\">ronddraaien<\/a><\/noindex>, en geavanceerde methoden waarbij de sessie van de klant wordt bewaard, zodat deze elke keer naar dezelfde server gaat als eerder. Wij wilden de tweede optie implementeren.<\/p>\n<p>In HAProxy wordt voor het behouden van klantensessies gebruikgemaakt van stick-tables. Deze slaan het originele IP-adres van de klant, het gekozen doeladres (backend) en bepaalde administratieve informatie op. Gewoonlijk worden stick-tabellen gebruikt om het paar source-IP + destination-IP op te slaan, wat vooral nuttig is voor applicaties die geen gebruikerssessie-context kunnen doorgeven wanneer ze overschakelen naar een andere load balancer, bijvoorbeeld in RoundRobin-balanceringsmodus.<\/p>\n<p>Als we de stick-tabel leren verplaatsen tussen verschillende HAProxy-processen (waar tussen de balans plaatsvindt), kunnen onze load balancers met \u00e9\u00e9n pool van stick-tabellen werken. Dit maakt naadloze netwerkoverschakeling voor de klant mogelijk wanneer een van de load balancers uitvalt, en de verwerking van klantensessies kan doorgaan op dezelfde backends die eerder waren gekozen.<\/p>\n<p>Voor een correcte werking moet het probleem met het source IP-adres van de load balancer waarmee de sessie is ingesteld, worden opgelost. In ons geval is dit een dynamisch adres op de loopback-interface. <\/p>\n<p>De juiste werking van peers wordt alleen onder bepaalde omstandigheden bereikt. Dit betekent dat TCP-timeouts groot genoeg moeten zijn of dat de overschakeling voldoende snel moet zijn, zodat de TCP-sessie niet verbroken raakt. Desondanks maakt dit een naadloze overschakeling mogelijk. <\/p>\n<p>Bij ons in IaaS hebben we een service die op dezelfde technologie is gebouwd. Dit is <noindex><a rel=\"nofollow\" href=\"https:\/\/mcs.mail.ru\/app\/services\/infra\/balancers-list\/\">Load Balancer als een service voor OpenStack<\/a><\/noindex>, genaamd Octavia. Het is gebaseerd op een set van twee HAProxy-processen, waarin van huis uit ondersteuning voor peers is ingebouwd. In deze service hebben ze zich uitstekend bewezen.<\/p>\n<p>Op de afbeelding is schematisch de verplaatsing van peers-tabellen tussen drie HAProxy-instanties weergegeven, met een voorgestelde configuratie voor hoe dit kan worden ingesteld:<\/p>\n<p><img decoding=\"async\" alt=\"Hoe wordt een failover-webarchitectuur gerealiseerd in het Mail.ru Cloud Solutions-platform\" src=\"\/wp-content\/uploads\/2019\/11\/d31fab761da627923345b7ace7f0b943.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>HAProxy Peers (sessiesynchronisatie)<\/i><\/p>\n<p>Als je een dergelijk schema gaat implementeren, moet je de werking zorgvuldig testen. Het is niet gegarandeerd dat het in precies dezelfde vorm 100% van de tijd werkt. Maar in ieder geval zul je de stick-tabellen niet verliezen wanneer je het source IP van de client moet onthouden.<\/p>\n<h2>Beperking van het aantal gelijktijdige verzoeken van dezelfde klant<\/h2>\n<p>\nElke service die openbaar toegankelijk is, inclusief onze API's, kan worden blootgesteld aan een instroom van verzoeken. De redenen hiervoor kunnen heel divers zijn, van gebruikersfouten tot gerichte aanvallen. We worden periodiek DDoS-aanvallen via IP-adressen. Klanten maken vaak fouten in hun scripts, wat ons mini-DDoS-aanvallen oplevert.<\/p>\n<p>Hoe dan ook, het is noodzakelijk om aanvullende bescherming te overwegen. Een voor de hand liggende oplossing is om het aantal verzoeken aan de API te beperken en geen processorcapaciteit te verspillen aan het verwerken van kwaadaardige verzoeken.<\/p>\n<p>Voor het implementeren van dergelijke beperkingen gebruiken we rate limits, georganiseerd op basis van HAProxy, met behulp van dezelfde stick-tabellen. De limieten zijn eenvoudig in te stellen en stellen ons in staat om de gebruiker te beperken op het aantal verzoeken aan de API. Het algoritme onthoudt het source IP van waaruit verzoeken worden gedaan en beperkt het aantal gelijktijdige verzoeken van \u00e9\u00e9n gebruiker. Uiteraard hebben we het gemiddelde belastingprofiel van de API voor elke service berekend en een limiet ingesteld die ongeveer 10 keer zo hoog is als deze waarde. We blijven de situatie nauwlettend in de gaten houden en blijven alert.<\/p>\n<p>Hoe ziet het eruit in de praktijk? We hebben klanten die voortdurend gebruikmaken van onze API's voor automatische schaling. Ze cre\u00ebren 's ochtends ongeveer tweehonderd tot driehonderd virtuele machines en verwijderen ze 's avonds weer. Voor OpenStack vergt het maken van een virtuele machine, inclusief PaaS-diensten, minimaal 1000 API-aanroepen, aangezien de interactie tussen de diensten ook via API's verloopt. <\/p>\n<p>Dergelijk geknutselt met taken veroorzaakt een aanzienlijke belasting. We hebben deze belasting ge\u00ebvalueerd, de dagelijkse pieken verzameld, en deze met tien vermenigvuldigd, en dat is onze rate-limiet geworden. We houden vinger aan de pols. Vaak zien we bots en scanners die ons proberen te bekijken om te zien of we CGA-scripts hebben die kunnen worden uitgevoerd; we snijden ze actief af.<\/p>\n<h2>Hoe de codebasis onopgemerkt voor gebruikers bij te werken<\/h2>\n<p>\nWe implementeren ook failover op het niveau van het uitrollen van code. Bij uitrol kunnen er fouten optreden, maar hun impact op de beschikbaarheid van diensten kan geminimaliseerd worden.<\/p>\n<p>We updaten voortdurend onze diensten en moeten het proces van het bijwerken van de codebasis waarborgen zonder effect voor gebruikers. Deze uitdaging hebben we opgelost met behulp van de beheermogelijkheden van HAProxy en de implementatie van Graceful Shutdown in onze diensten.<\/p>\n<p>Voor het oplossen van deze taak was het nodig om het beheer van de load balancer en het 'juiste' uitschakelen van diensten te waarborgen:<\/p>\n<ul>\n<li>In het geval van HAProxy gebeurt het beheer via een stats-bestand, wat in feite een socket is en in de HAProxy-configuratie wordt gedefinieerd. Commando's kunnen via stdio aan hem worden doorgegeven. Maar ons voornaamste hulpmiddel voor het controleren van configuraties is Ansible, en daarom heeft het een ingebouwde module voor het beheren van HAProxy, die we actief gebruiken. <\/li>\n<li>Het grootste deel van onze API- en Engine-diensten ondersteunt technieken voor een graceful shutdown: bij uitschakeling wachten ze tot de huidige taak volledig is afgerond, of het nu een http-verzoek is of een andere service-taak. Hetzelfde geldt voor de worker. Deze is op de hoogte van alle taken die hij uitvoert en stopt pas als alles succesvol is afgerond. <\/li>\n<\/ul>\n<p>\nDankzij deze twee punten ziet ons veilige uitrolalgoritme er als volgt uit.<\/p>\n<ol>\n<li>De ontwikkelaar verzamelt een nieuw codepakket (dit is bij ons een RPM), test het in de dev-omgeving, test het in de stage, en laat het in de stage-repository.<\/li>\n<li>De ontwikkelaar stelt de taak voor de implementatie met een zo gedetailleerd mogelijke beschrijving van de \u00abartefacten\u00bb: versie van het nieuwe pakket, beschrijving van de nieuwe functionaliteit en andere details over de implementatie indien nodig.<\/li>\n<li>De systeemadministrator start de update. Hij voert het Ansible-playbook uit, dat op zijn beurt het volgende doet: \n<ul>\n<li>Het pakket uit de stage-repository wordt gehaald, en daarop wordt de versie van het pakket in de productrepository bijgewerkt.<\/li>\n<li>Er wordt een lijst van backends van de te updaten service opgesteld.<\/li>\n<li>De eerste te updaten service in HAProxy wordt uitgeschakeld en er wordt gewacht tot de processen zijn be\u00ebindigd. Dankzij graceful shutdown zijn we ervan verzekerd dat alle huidige klantverzoeken succesvol zullen worden afgerond.<\/li>\n<li>Na de volledige stopzetting van de API, workers en het uitschakelen van HAProxy, vindt er een code-update plaats.<\/li>\n<li>Ansible start de services.<\/li>\n<li>Voor elke service worden specifieke \u00abhandvaten\u00bb geactiveerd die unit-tests uitvoeren op een aantal vooraf bepaalde belangrijke tests. Er vindt een basiscontrole van de nieuwe code plaats.<\/li>\n<li>Als er in de vorige stap geen fouten zijn gevonden, wordt de backend geactiveerd.<\/li>\n<li>We gaan naar de volgende backend.<\/li>\n<\/ul>\n<\/li>\n<li>Na de update van alle backends worden functionele tests uitgevoerd. Als deze onvoldoende zijn, kijkt de ontwikkelaar naar eventuele nieuwe functionaliteit die hij heeft ontwikkeld.<\/li>\n<\/ol>\n<p>\nMet deze is de implementatie voltooid.<\/p>\n<p><img decoding=\"async\" alt=\"Hoe wordt een failover-webarchitectuur gerealiseerd in het Mail.ru Cloud Solutions-platform\" src=\"\/wp-content\/uploads\/2019\/11\/2d889fe1af33653e4bfebabe1cce6552.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>De cyclus van de service-update<\/i><\/p>\n<p>Dit schema zou niet werkend zijn geweest als we niet \u00e9\u00e9n regel hadden. We ondersteunen tegelijkertijd de oude en de nieuwe versie in productie. Tijdens de softwareontwikkeling wordt al ingepland dat, zelfs als er wijzigingen in de database van de service zijn, deze de vorige code niet zullen breken. Als gevolg daarvan vindt een geleidelijke update van de codebasis plaats.<\/p>\n<h2>Conclusie<\/h2>\n<p>\nAls ik mijn gedachten deel over een fouttolerante WEB-architectuur, wil ik nogmaals de belangrijkste punten benadrukken:<\/p>\n<ul>\n<li>fysieke fouttolerantie;<\/li>\n<li>netwerkfouttolerantie (load balancers, BGP);<\/li>\n<li>fouttolerantie van de gebruikte en ontwikkelde software.<\/li>\n<\/ul>\n<p>\nIedereen een stabiele uptime!<br \/>\n<br \/>Bron: <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\/nl\/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=\"nl_NL\" \/>\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\/nl\/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\udd47Hoe wordt een fouttolerante webarchitectuur gerealiseerd op het Mail.ru Cloud Solutions-platform | ProHoster","description":".","canonical_url":"https:\/\/prohoster.info\/nl\/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":"nl_NL","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\/nl\/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\/nl\/wp-json\/wp\/v2\/posts\/52389","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/comments?post=52389"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/52389\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media?parent=52389"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/categories?post=52389"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/tags?post=52389"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}