Kuidas rakendatakse veakindlat veebiarhitektuuri Mail.ru Cloud Solutions platvormil.

Kuidas rakendatakse veakindlat veebiarhitektuuri Mail.ru Cloud Solutions platvormil.

Tere, Habr! Mina olen Artem Karamyšev, süsteemiadministreerimise meeskonna juht Mail.Ru Cloud Solutions (MCS). Viimase aasta jooksul oleme käivitanud palju uusi tooteid. Soovisime saavutada, et API-teenused oleksid kergesti skaleeritavad, taluvuskatkestuste suhtes vastupidavad ja kiiresti kasvava kasutajakoormuse jaoks valmis. Meie platvorm põhineb OpenStackil ning tahan rääkida, milliseid taluvuskatkestuste probleeme pidime lahendama, et saada töökindel süsteem. Arvan, et see huvitab ka neid, kes arendavad tooteid OpenStackil.

Platvormi kogutaluvuskatkestus tuleneb selle komponentide vastupidavusest. Nii et läheme järk-järgult läbi kõik tasemed, kus me avastasime riske ja lahendasime neid.

Selle loo videoversiooni, mille algallikaks on ettekande Uptime day 4 konverentsil, korraldas ITSumma, saab vaadata Uptime Community YouTube kanalilt.

Füüsilise arhitektuuri taluvuskatkestus

MCSi avalikuks mõeldud pilv asub praegu kahes Tier III andmekeskuses, mille vahel on füüsilisel tasandil erinevate marsruutide peal testitud tume kiud, mille läbilaskevõime on 200 Gbit/s. Tier III tase tagab vajalikud füüsilise infrastruktuuri tõrketaluvuse.

Tume kiud on reserveeritud nii füüsilisel kui ka loogilisel tasandil. Kanalite reserveerimise protsess oli iteratiivne, esines probleeme ja me täiustame pidevalt andmekeskuste vahelist ühendust.

Näiteks hiljuti, kui töötati kaevanduses, mis asub ühe andmekeskuse lähedal, lõhkus ekskavaator toru, milles asusid nii põhja- kui varuoptilised kaablid. Meie andmekeskuse vaheline tõrketaluv kanal osutus ühes punktis, kaevanduses, haavatavaks. Seega kaotasime osa infrastruktuurist. Tehaseime järeldusi, tegime mitmeid meetmeid, sealhulgas paigaldasime täiendava optika naaberkaevandusse.

Andme центrites on sidepakkujate kohaloleku punkte, kellele me edastame oma eelistusi BGP kaudu. Iga võrgu suunas valitakse parim mõõdik, mis võimaldab tagada erinevatele klientidele parimat ühenduse kvaliteeti. Kui ühendus ühe pakkujaga katkeb, muutume me oma marsruutimist kergesti teiste pakkujate kaudu.

Teenusepakkuja rikkega juhtudel lülitume automaatselt järgmiseks. Kui üks andme keskus ebaõnnestub, on meil teises andme keskuses peegellik koopia meie teenustest, mis võtab kogu koormuse enda kanda.

Kuidas rakendatakse veakindlat veebiarhitektuuri Mail.ru Cloud Solutions platvormil.
Füüsilise infrastruktuuri tõrgeteta töö

Mida me kasutame rakendustasandi tõrgeteta töö tagamiseks

Meie teenus põhineb mitmetel avatud lähtekoodiga komponentidel.

ExaBGP — teenus, mis rakendab mitmeid funktsioone dünaamilise marsruutimise protokolli abil BGP raames. Me kasutame seda aktiivselt, et kuulutada välja meie valge IP-aadresse, mille kaudu kasutajad pääsevad juurde API-le.

HAProxy — kõrge koormusega laadimisjaotur, mis võimaldab seadistada väga paindlikke liikluse jaotamise reegleid erinevatel OSI mudeli tasanditel. Me kasutame seda kõigi teenuste, nagu andmebaasid, sõnumite vahetajad, API-teenused, veebi-teenused ning meie siseprojektid, tasakaalustamiseks — kõik on HAProxy taga.

API rakendus — veebirakendus, mis on kirjutatud pythonis, mille abil kasutaja haldab oma infrastruktuuri ja teenuseid.

Töötleja rakendus (edasi on lihtsalt töötleja) — OpenStack teenustes on see infrastruktuuri demon, mis võimaldab edastada API käske infrastruktuurile. Näiteks luuakse ketas just töötlejas, samas kui luua soovitakse API rakenduses.

OpenStack rakenduse standardarhitektuur

Enamik teenuseid, mis on välja töötatud OpenStacki jaoks, püüavad järgida ühtset paradigmat. Teenus koosneb tavaliselt kahest osast: API ja töötlusprotsessidest (töötajad). Üldiselt on API WSGI-rakendus Pythonis, mis töötab kas iseseisva protsessina (daemon) või juba olemasoleva veebiserveri, nagu Nginx või Apache, kaudu. API töötleb kasutaja päringut ja edastab edasised juhised töötlusrakendusele. Edastamine toimub sõnumibrokeri kaudu, milleks on tavaliselt RabbitMQ, teised on halvasti toetatud. Kui sõnumid satuvad brookerisse, töötlevad neid töötajad ja vajadusel tagastavad vastuse.

See paradigma eeldab eraldatud ühiseid rikkepunkte: RabbitMQ ja andmebaasi. Ent RabbitMQ on isoleeritud ühe teenuse piires ja idee järgi võib see olla iga teenuse jaoks individuaalne. Seetõttu jagame MCSis need teenused maksimaalselt, iga eraldi projekti jaoks loome eraldi andmebaasi ja eraldi RabbitMQ. See lähenemine on hea, kuna hädaolukorras mõnes haavatavas punktis ei riku kogu teenust, vaid ainult selle osa.

Worker application'i arvu pole piiratud, seega saab API hõlpsasti horisontaalselt rööpuda koormuse tasakaalustajate tagajärjel, et suurendada jõudlust ja hädavajalikkust.

Mõnedes teenustes on vajalik koordineerimine teenuse sees – kui toimub keerulisi järjestikuseid operatsioone API ja worker'ite vahel. Sellisel juhul kasutatakse ühte koordineerimisagentuuri, nagu Redis, Memcache, etcd, mis võimaldab ühel worker'il öelda teisele, et see ülesanne on tema käsutuses („palun ära seda võta“). Me kasutame etcd-d. Tüüpiliselt suhtlevad worker'id aktiivselt andmebaasiga, kirjutades ja lugedes sealt teavet. Meie andmebaasina kasutame mariadb'd, mis asub meil multimeister-klusteris.

Selline klassikaline üksikteenus on korraldatud OpenStacki tavapärasel viisil. Seda saab vaadelda kui isoleeritud süsteemi, mille jaoks on piisavalt selged meetodid skaleerimise ja kriitilisuse tagamiseks. Näiteks kriitilisuse tagamiseks piisab API-de ette koormustasakaalustaja paigaldamisest. Worker'ite skaleerimine saavutatakse nende arvu suurendamise teel.

Kogu süsteemi nõrk koht on RabbitMQ ja MariaDB. Nende arhitektuur väärib eraldi artiklit. Selles artiklis tahan keskenduda API-le ja selle tõrkekindlusele.

Kuidas rakendatakse veakindlat veebiarhitektuuri Mail.ru Cloud Solutions platvormil.
OpenStack rakenduse arhitektuur. Pilveplatvormi tasakaalustamine ja tõrkekindlus.

Teeme HAProxy tasakaalustajast tõrkekindla ExaBGP abil.

Kuna meie API-d peavad olema skaleeritavad, kiire ja tõrkekindlad, paigaldasime nende ette tasakaalustaja. Valisime HAProxy. Minu arvates omab see kõiki vajalikke omadusi meie ülesande jaoks: tasakaalustamine mitmetel OSI tasemetel, haldusliides, paindlikkus ja skaleeritavus, suur hulk tasakaalustamismeetodeid, sessioonitabelite toetus.

Esimene probleem, mille lahendamine oli vajalik, oli tasakaalustaja enda tõrkekindlus. Lihtne tasakaalustaja paigaldamine loob samuti tõrkepunkte: kui tasakaalustaja rikki läheb – teenus kukub välja. Selle vältimiseks kasutasime HAProxy koos ExaBGP-ga.

ExaBGP võimaldab teenuse oleku kontrollimise mehhanismi rakendamist. Kasutasime seda mehhanismi HAProxy töökindluse kontrollimiseks ja probleemide korral HAProxy teenuse BGP-st väljalülitamiseks.

ExaBGP+HAProxy skeem

  1. Paigaldame kolmele serverile vajaliku tarkvara, ExaBGP ja HAProxy.
  2. Igal serveril loome loopback-liidese.
  3. Kõikidel kolmel serveril määrame sellele liidesele sama avaliku IP-aadressi.
  4. Avalikult IP-aadress anoneeritakse internetis läbi ExaBGP.

Klienditeenuste töökindlus saavutatakse, anoneerides sama IP-aadressi kõigilt kolmest serverist. Võrgupoolest on sama aadress kättesaadav kolmest erinevast järgmise hüppena. Router näeb kolme sama marsruuti, valib oma mõõdikutest lähtuvalt kõige prioriteetsema (mis on tavaliselt sama valik) ja liiklus suunatakse ainult ühte serverisse.

Probleemide korral HAProxy tööga või serveri rikke puhul lõpetab ExaBGP marsruudi anoneerimise ja liiklus suunatakse sujuvalt teisele serverile.

Nii oleme saavutanud tasakaalustaja töökindluse.

Kuidas rakendatakse veakindlat veebiarhitektuuri Mail.ru Cloud Solutions platvormil.
HAProxy tasakaalustajate töökindlus

Skeem ei osutunud ideaalseteks: me õppisime HAProxy varundamisest, kuid mitte koormuse jaotamisest teenuste sees. Seetõttu laiendasime skeemi veidi: läksime üle mitmete valgete IP-aadresside vahelisele tasakaalustamisele.

DNS ja BGP põhine tasakaalustamine

Koormuse tasakaalu küsimus meie HAProxy ees jäi lahendamata. Siiski on sellelahendamine suhteliselt lihtne, nagu me seda enda juures tegime.

Kolme serveri tasakaalustamiseks on vajalik 3 valget IP-aadressi ja hea vana DNS. Igaüks neist aadressidest määratakse igale HAProxy'le loopback-liideses ja kuulutatakse internetti.

OpenStackis kasutatakse ressursse haldava teenuste katalooge, kus määratakse iga teenuse API lõpp-punkt. Selles kataloogis määrame domeeninime — public.infra.mail.ru, mis lahendatakse DNSi kaudu kolme erineva IP-aadressiga. Tulemuseks on koormuse jaotus kolme aadressi vahel DNSi kaudu.

Kuna me ei kontrolli serverite valimise prioriteete valgete IP-aadresside kuulutamisel, ei ole see tasakaalustus. Üldiselt valitakse ainult üks server IP-aadressi vanuse järgi, samas kui kaks teist jäävad ootama, kuna BGP-s ei ole mingeid mõõdikuid määratud.

Oleme hakanud edastama marsruute ExaBGP kaudu erinevate mõõdikatega. Iga tasakaalustaja kuulutab kõik kolm valget IP-aadressi, kuid üks neist, mis on antud tasakaalustaja jaoks peamine, kuulutatakse minimaalse mõõdikaga. Nii kaua, kui kõik kolm tasakaalustajat on töökorras, jõuavad päringud esimesse IP-aadressi esimesse tasakaalustajasse, teisesse teise ja kolmandasse kolmandasse.

Mis juhtub hetkel, kui üks tasakaalustaja kukub? Kui ükski tasakaalustaja ebaõnnestub, kuulutatakse tema põhiadress ikka veel kahe teise kaudu, liiklus nende vahel jaotatakse ümber. Nii anname kasutajale DNS-i kaudu kohe mitu IP-aadressi. DNS-i tasakaalu ja erinevate mõõdikate kaudu saavutan tasakaalustatud koormuse jaotuse kõigi kolme tasakaalustaja vahel, samal ajal mitte kaotades rikke taluvust.

Kuidas rakendatakse veakindlat veebiarhitektuuri Mail.ru Cloud Solutions platvormil.
HAProxy tasakaalustus DNS-i + BGP baasil

ExaBGP ja HAProxy vaheliseks suhtluseks

Nii oleme rakendanud talitluse katkestamise vältimist, mis põhineb marsruutide anname lõpetamisel. Kuid HAProxy võib sulgeda ka muudel põhjustel, kui serveri rike: haldustõrked, teenuse sisemised probleemid. Soovime eemaldada purunenud koormaja koormusest ka nendes olukordades, ja selleks on vajalik teine mehhanism.

Seega, laiendades eelmist skeemi, rakendasime ExaBGP ja HAProxy vahelise heartbeat'i. See on tarkvaraline rakendus, mis võimaldab ExaBGP-l kasutada kohandatud skripte rakenduste seisundi kontrollimiseks.

Selleks tuleb ExaBGP konfiguratsioonis seadistada health checker, mis suudab kontrollida HAProxy staatust. Meie juhul seadistasime HAProxy-s tervise tagamise taustteenuse, ning ExaBGP-l kontrollime seda lihtsa GET päringu kaudu. Kui anname haru lõpetab, siis on HAProxy tõenäoliselt mittetoimiv ning selle reklaamimine ei ole vajalik.

Kuidas rakendatakse veakindlat veebiarhitektuuri Mail.ru Cloud Solutions platvormil.
HAProxy tervisekontroll

HAProxy sõbrad: sessioonide sünkroniseerimine

Järgmine samm, mis tuli ette võtta, oli sessioonide sünkroniseerimine. Jaotatud tasakaalustajate kaudu töötades on keeruline korraldada kliendi sessiooniteabe salvestamist. Kuid HAProxy on üks väheseid tasakaalustajaid, mis suudab seda teha Peers funktsiooni kaudu — võimalus edastada HAProxy erinevate protsesside vahel sessioonitabeleid.

On erinevaid tasakaalustamismeetodeid: lihtsad, nagu ring-levi, ja täiustatud, kus salvestatakse kliendi sessioon ja ta pääseb igal korral samale serverile, kuhu ta enne jõudis. Soovisime teostada teist varianti.

HAProxy-s kasutatakse kliendi sessioonide salvestamiseks selle mehhanismi stick-tables. Need salvestavad kliendi algse IP-aadressi, valitud sihtaadressi (tagasi) ja teatud teenuseteabe. Üksikasjalikult kasutatakse stick-tabeleid paaride source-IP + destination-IP säilitamiseks, mis on eriti kasulik rakenduste jaoks, mis ei suuda edastada kasutaja sessiooni konteksti teisele tasakaalustajale lülitamisel, näiteks — RoundRobin'i tasakaalustamisrežiimis.

Kui stick-tabelit õpetada HAProxy erinevate protsesside vahel liikuma (mille vahel toimub tasakaalustamine), saavad meie tasakaalustajad töötada ühe stick-tabelite kogumiga. See võimaldab sujuvat kliendi võrgu vahetust, kui üks tasakaalustajatest viga läheb, ning kliendi sessioonid jätkuvad juba valitud backend-idel.

Õige töö tagamiseks peab olema lahendatud tasakaalustaja source IP-aadress, millelt sessioon on loodud. Meie puhul on see dünaamiline aadress loopback-liideses.

Peers'i õige töö saavutatakse vaid teatud tingimustes. See tähendab, et TCP-taimerid peavad olema piisavalt suured või vahetus peab olema piisavalt kiire, et TCP-sessioon ei katkeks. Siiski võimaldab see sujuvat vahetust.

Meil on IaaS-is teenus, mis on loodud sama tehnoloogia alusel. See Load Balancer kui teenus OpenStackile, mida nimetatakse Octaviaks. See põhineb kahel HAProxy protsessil ja sellel on esialgselt toetatud peers. Selles teenuses on nad end tõestanud.

Pildil on scheemaatiliselt kujutatud peers-tabelite liikumine kolme HAProxy eksemplari vahel, pakutud on konfiguratsioon, kuidas seda seadistada:

Kuidas rakendatakse veakindlat veebiarhitektuuri Mail.ru Cloud Solutions platvormil.
HAProxy Peers (sessioonide sünkroniseerimine)

Kui kavatsete rakendada samasugust skeemi, tuleb selle toimimist hoolikalt testida. Pole kindel, et see töötab 100% juhtudest samamoodi. Kuid vähemalt ei kaota te stick-tabeleid, kui on vajalik meeles pidada kliendi source IP-d.

Klassiülesannete limiit ühelt jaolt kliendilt

Kõik teenused, mis on avalikult kättesaadavad, sealhulgas meie API-d, võivad olla vastuvõtlikud päringute laviinidele. Nende põhjused võivad olla äärmiselt erinevad, alates kasutajate vigadest kuni sihitud rünnakuteni. Meid DDoS-itatakse perioodiliselt IP-aadresside kaudu. Klientidel on sageli oma skriptides vigu, tehes meile mini-DDoS-e.

Igatahes on vajalik ette nähtud lisakaitse. Ilmselge lahendus on piirata API päringute arvu ja mitte kulutada protsessorite aega kahjulike päringute töötlemiseks.

Sarnaste piirangute rakendamiseks kasutame rate limiite, mis on korraldatud HAProxy baasil, sama stick-tabelite abil. Limiite seadistatakse piisavalt lihtsalt ja need võimaldavad piirata kasutajat API-päringute arvu järgi. Algoritm mäletab allika IP-aadressi, millelt päringud tulevad, ja piirab sama kasutaja samaaegsete päringute arvu. Loomulikult oleme arvutanud iga teenuse API keskmise koormusprofiili ning seadnud limiidiks ≈ 10 korda rohkem kui see väärtus. Jätkame siiani olukorra hoolikat jälgimist, hoides käe pulsil.

Kuidas see praktikas välja näeb? Meil on kliente, kes kasutavad pidevalt meie API-sid automaatseks skaleerimiseks. Nad loovad umbes kakssada-kolmsada virtuaalmasinat hommikul ja eemaldavad need õhtul. OpenStacki jaoks virtuaalmasina loomine koos PaaS-teenustega tähendab vähemalt 1000 API-päringut, kuna teenuste vaheline suhtlus toimub samuti API kaudu.

Selliste ülesannete ümberjaotused tekitavad üsna suurt koormust. Me oleme selle koormuse hinnanud, kogunud päevased tipud, suurendanud need kümme korda ja see on saanud meie rate-limiidiks. Me jälgime olukorda pidevalt. Sageli näeme roboteid, skaneerijaid, kes püüavad uurida, kas meil on mõni CGA-skript, mida käivitada, ja me lõikame need aktiivselt maha.

Kuidas uuendada koodibaasi kasutajatele märkamatult

Kasutame ka koodide juurutamise tasemel rikekindlust. Juurutamisel võivad tekkida vead, kuid nende mõju teenuste kättesaadavusele on võimalik minimeerida.

Uuendame pidevalt oma teenuseid ja peame tagama koodibaasi uuendamise protsessi kasutajatele märkamatult. Selle ülesande lahendamine on võimalik tänu HAProxy juhtimise võimalustele ja meie teenustes Graceful Shutdown rakendamisele.

Selle probleemi lahendamiseks oli vajalik tagada koormuse jaoturi juhtimine ja teenuste 'õige' väljalülitamine:

  • HAProxy puhul toimub juhtimine stats-faili kaudu, mis on tegelikult socket ja määratakse HAProxy konfiguris. Käskude edastamine toimub stdio kaudu. Kuid meie peamine tööriist konfiguratsioonide kontrollimiseks on ansible, seega on seal sisseehitatud moodul HAProxy haldamiseks, mida me aktiivselt kasutame.
  • Enamik meie teenuseid API ja Engine toetavad tehnoloogiat graceful shutdown: väljalülitamisel ootavad nad, kuni praegune ülesanne, olgu see http-päring või mõni muu teenusülesanne, on täielikult lõpetatud. Sama juhtub ka töötlusega. Töötlus teab kõiki ülesandeid, mida ta täidab, ja lõpetab, kui kõik on edukalt lõpule viidud.

Nende kahe punkti tõttu näeb meie turvaline juurutusalgoritm välja järgmine.

  1. Arendaja koostab uue koodipaketi (meie puhul on see RPM), testib arenduskeskkonnas, testib ststage, ja jätab ststage-repositooriumisse.
  2. Arendaja seab juurutamise ülesande, esitades võimalikult detailsed kirjeldused "artefaktidest": uue paketi versioon, uue funktsionaalsuse kirjeldus ja muud üksikasjad juurutamise kohta vajadusel.
  3. Süsteemiadministraator alustab värskendust. Käivitab Ansible'i playbook'i, mis omakorda teeb järgmist:
    • Võtab paketi stage-repositoriumist ja värskendab paketi versiooni tootmisrepoos.
    • Koostab loendi värskendatavast teenuse tagaplaanist.
    • Lülitab välja esimese värskendatava teenuse HAProxy's ja ootab, kuni selle protsessid on lõpetatud. Tänu gracefull shutdown'ile oleme kindlad, et kõik aktiivsed kliendikutsed lõpetatakse edukalt.
    • Pärast API, töötajate ja HAProxy täielikku seiskamist toimub koodi värskendamine.
    • Ansible käivitab teenused.
    • Iga teenuse jaoks tõmbab ta kindlad 'nupud', mis teevad unit-testimise eelnevalt määratud võtmetestide seeria järgi. Teostatakse uue koodi põhikontroll.
    • Kui eelmisel sammul vigu ei leitud, aktiveeritakse tagaplaan.
    • Liigume järgmise tagaplaani juurde.
  4. Pärast kõigi tagaplaanide värskendamist käivitatakse funktsionaaltestid. Kui neid on puudu, vaatab arendaja igat uut funktsiooni, mille ta tegi.

Sellega on juurutamine lõpetatud.

Kuidas rakendatakse veakindlat veebiarhitektuuri Mail.ru Cloud Solutions platvormil.
Teenuse värskendamise tsükkel

See skeem ei oleks töövõimeline, kui meil ei oleks ühte reeglit. Me hoiame korraga töös nii vana kui ka uut versiooni. Ettevalmistuse käigus, tarkvara arendamise faasis, on sisse seatud, et isegi kui teenuse andmebaasis on muudatusi, ei riku need eelnevat koodi. Tulemusena toimub koodibaasi järkjärguline uuendamine.

Kokkuvõte

Jagades enda mõtteid veakindla WEB-arhitektuuri kohta, soovin veel kord rõhutada selle võtmeaspekte:

  • füüsiline veakindlus;
  • võrgustiku veakindlus (koormuse tasakaalustajad, BGP);
  • kasutatavate ja arendatavate rakenduste veakindlus.

Soovin kõigile stabiilset uptime'i!

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster