
God dag alle sammen!Â
Jeg heter Nikita, jeg er teamleder for ingeniĂžrteamet i Cian. En av mine oppgaver i selskapet er Ă„ redusere antall hendelser relatert til infrastrukturen i produksjon til null.
Det som vil bli diskutert videre, har gitt oss mye smerte, og mĂ„let med denne artikkelen er Ă„ hindre andre fra Ă„ gjenta vĂ„re feil, eller i det minste minimere deres innvirkning.Â
Forord
For lenge siden, nĂ„r Cian bestod av monolitter, og det ikke var noen tegn pĂ„ mikrotjenester, mĂ„lte vi tilgjengeligheten av ressursen ved Ă„ sjekke 3â5 sider.Â
Svarte â alt er bra, svarer ikke etter lang tid â alert. Hvor lenge de mĂ„ vĂŠre nede for at det skal betraktes som en hendelse, ble avgjort av folk pĂ„ mĂžter. IngeniĂžrteamet var alltid involvert i etterforskningen av hendelsen. NĂ„r etterforskningen var fullfĂžrt, skrev vi et postmortem â en slags rapport sendt pĂ„ e-post i formatet: hva som skjedde, hvor lenge det varte, hva vi gjorde i Ăžyeblikket, hva vi vil gjĂžre i fremtiden.Â
De viktigste sidene pÄ nettstedet eller hvordan vi forstÄr at vi har truffet bunnen
Â
For Ă„ kunne forstĂ„ prioriteten til feilen, identifiserte vi de mest kritiske sidene for forretningsfunksjonaliteten pĂ„ nettstedet. For disse sidene teller vi antall vellykkede/ mislykkede forespĂžrsel og tidsavbrudd. PĂ„ denne mĂ„ten mĂ„ler vi oppetid.Â
La oss si at vi har funnet ut at det er flere superviktige seksjoner pĂ„ nettstedet som er ansvarlige for hovedtjenesten â sĂžk og innlevering av annonser. Hvis antall forespĂžrsel som resulterte i feil overskrider 1% â er det en kritisk hendelse. Hvis prosentandelen av feil overskrider 0,1% i lĂžpet av 15 minutter i rushtiden â betraktes dette ogsĂ„ som en kritisk hendelse. Disse kriteriene dekker de fleste hendelser, mens andre gĂ„r utenfor rammen av denne artikkelen.

Top beste hendelsene til Cian
SĂ„ vi har absolutt lĂŠrt Ă„ identifisere at en hendelse har skjedd.Â
NĂ„ er hver hendelse detaljert beskrevet og reflektert i en episk Jira. For ordens skyld: for dette opprettet vi et eget prosjekt, kalt FAIL â her kan det kun opprettes episoder.Â
Hvis vi samler alle feilene fra de siste Ă„rene, er de ledende:Â
- hendelser relatert til mssql;
- hendelser forÄrsaket av eksterne faktorer;
- administrasjonsfeil.
La oss gÄ mer detaljert inn pÄ administrasjonsfeilene, samt noen andre interessante feil.
Femte plassen â «Vi rydder opp i DNS»
Det var en grĂ„ tirsdag. Vi bestemte oss for Ă„ rydde opp i DNS-klyngen.Â
Vi Ăžnsket Ă„ migrere interne DNS-servere fra BIND til PowerDNS, og dedikere helt separate servere til dette, hvor det bare kjĂžrer DNS.Â
Vi plasserte Ă©n DNS-server i hver lokasjon av vĂ„re datasentre, og tiden for Ă„ flytte sonene fra BIND til PowerDNS og bytte infrastrukturen til de nye serverne kom.Â
I det mest hektiske Þyeblikket under overfÞringen av alle servere, som ble oppgitt i de lokale cacherende BIND-serverne pÄ alle serverne, gjensto bare én, som befant seg i datasenteret i St. Petersburg. Dette datasenteret var opprinnelig deklarert som ikke-kritisk for oss, men ble plutselig en single point of failure.
Akkurat i lĂžpet av denne overfĂžringsperioden falt kanalen mellom Moskva og St. Petersburg. Vi sto faktisk uten DNS i fem minutter og kom opp igjen da hoster feilen var utbedret.Â
Konklusjoner:
Tidligere oversÄ vi eksterne faktorer under forberedelsene til arbeidet, men nÄ inkluderer vi ogsÄ dem i listen over hva vi mÄ forberede oss pÄ. NÄ streber vi etter at alle komponenter er reservert i n-2, og i lÞpet av arbeidene kan vi senke dette nivÄet til n-1.
- NÄr du lager handlingsplanen, noter punktene hvor tjenesten kan falle, og tenk pÄ scenarier der alt gÄr «sÄ dÄrlig som mulig» pÄ forhÄnd.
- Fordel interne DNS-servere pÄ forskjellige geolokasjoner/datasentre/stativer/brytere/inntak.
- Sett opp en lokal cacherende DNS-server pĂ„ hver server, som videresender forespĂžrslene til de primĂŠre DNS-serverne, og i tilfelle den ikke er tilgjengelig, vil svare fra cachen.Â
Fjerde plassen â «Vi rydder opp i Nginx»
En vakker dag bestemte teamet vĂ„rt at «nĂ„ er det nok», og prosessen med refaktorering av Nginx-konfigurasjonene ble igangsatt. HovedmĂ„let var Ă„ gjĂžre konfigurasjonene intuitivt forstĂ„elige. Tidligere var alt «historisk oppbygd» og inneholdt ikke noe logikk. NĂ„ har vi flyttet hver server_name til en tilsvarende fil og fordelt alle konfigurasjoner i mapper. For Ă„ si det slik â konfigurasjonen inneholder 253949 linjer eller 7836520 tegn og tar nesten 7 megabyte. Ăverste nivĂ„ av strukturen:Â
Nginx-struktur
âââ tilgang
â Â âââ allow.list
...
â Â âââ whitelist.conf
âââ geobase
â Â âââ exclude.conf
...
â Â âââ geo_ip_to_region_id.conf
âââ geodb
â Â âââ GeoIP.dat
â Â âââ GeoIP2-Land.mmdb
â Â âââ GeoLiteCity.dat
âââ inc
â Â âââ error.inc
...
â Â âââ proxy.inc
âââ lists.d
â Â âââ bot.conf
...
â Â âââ dynamic
â Â âââ geo.conf
âââ lua
â Â âââ cookie.lua
â Â âââ log
â Â â Â âââ log.lua
â Â âââ logics
â Â â Â âââ include.lua
â Â â Â âââ ...
â Â â Â âââ utils.lua
â Â âââ prom
â Â Â Â âââ stats.lua
â Â Â Â âââ stats_prometheus.lua
âââ map.d
â Â âââ access.conf
â Â âââ ..Â
â Â âââ zones.conf
âââ nginx.conf
âââ robots.txt
âââ server.d
â Â âââ cian.ru
â Â â Â âââ cian.ru.conf
â Â â Â âââ ...
â Â â Â âââ my.cian.ru.conf
âââ service.d
â Â âââ ...
â Â âââ status.conf
âââ upstream.d
    âââ cian-mcs.conf
    âââ ...
    âââ wafserver.confDet ble betydelig bedre, men i prosessen med Ă„ omdĂžpe og fordele konfigurasjoner hadde noen av dem feil filendelse og havnet ikke i direktivet include *.conf. Som et resultat ble deler av vertene utilgjengelige og ga 301 til hovedsiden. PĂ„ grunn av at svarkoden ikke var 5xx/4xx, ble dette ikke lagt merke til med en gang, men fĂžrst tidlig om morgenen. Etter dette begynte vi Ă„ skrive tester for Ă„ sjekke infrastrukturkomponentene.
Konklusjoner:Â
- Strukturer konfigurasjonene riktig (ikke bare nginx) og tenk gjennom strukturen tidlig i prosjektet. Dette vil gjÞre dem enklere Ä forstÄ for teamet, noe som igjen vil redusere TTM.
- Skriv tester for enkelte infrastrukturkomponenter. For eksempel: sjekk at alle nĂžkkelservere gir riktig status og kropp av svaret. Det er nok Ă„ ha noen skript tilgjengelig som tester hovedfunksjonene til komponenten, sĂ„ du ikke mĂ„ statte deg selv i panikk klokken tre om natten om hva mer som skal sjekkes.Â
Tredjeplassen - 'Plutselig var det ikke mer plass i Cassandra'
Dataene vokste jevnt, og alt var greit inntil det punktet hvor store cassandra-kapsekser begynte Ă„ feile ved vedlikehold fordi kompaktsjon ikke kan fungere.Â
PÄ en dÄrlig dag ble klusteret nesten til en gresskar, som sagt:
- det var omtrent 20% ledig plass totalt i klusteret;
- det er ikke mulig Ä legge til noder ordentlig fordi det ikke gjennomfÞres rensing etter Ä ha lagt til en node pÄ grunn av plassmangel pÄ partisjoner;
- ytelsen synker litt, siden kompaktsjon ikke fungerer;Â
- klusteret fungerer i nĂždmodus.

Ute â vi har lagt til fem flere noder uten rensing, hvoretter vi begynte Ă„ trekke dem systematisk ut av klyngen og deretter legge dem inn igjen som tomme noder som har fylt opp plassen. Tiden brukt har vĂŠrt betydelig mer enn Ăžnsket. Det var risiko for delvis eller full utilgjengelighet av klyngen.Â
Konklusjoner:
- PĂ„ alle servere bĂžr cassandra ha opptil 60 % av plassen brukt pĂ„ hver partisjon.Â
- De bĂžr vĂŠre lastet opp til maksimalt 50 % av CPU.
- Ikke undervurder kapasitetsplanlegging, og det bÞr tenkes pÄ for hver komponent med hensyn til dens spesifikasjoner.
- Jo flere noder i klyngen, desto bedre. Servere som inneholder en liten mengde data, blir raskere gjenopprettet, og en slik klynge er lettere Ă„ reaktivere.Â
Andreplass â «Dataene forsvant fra konsulens key-value-lagring»
For tjenestegjenkjenning bruker vi, som mange andre, konsul. Men vi bruker ogsĂ„ dens key-value for blue-green distribusjon av monolittisk programvare. Der lagres informasjon om aktive og inaktive upstreams, som bytter plass under distribusjonen. For dette ble det skrevet en distribusjonstjeneste som interagerte med KV. PĂ„ et tidspunkt forsvant dataene fra KV. Vi gjenopprettet dem fra hukommelsen, men med en rekke feil. FĂžlgelig ble belastningen pĂ„ upstreamene fordelt ujevnt under distribusjonen, og vi fikk mange 502-feil pĂ„ grunn av overbelastning av backendene pĂ„ CPU. Til slutt flyttet vi fra konsul KV til postgres, hvor det er mye vanskeligere Ă„ slette dem. Â
Konklusjoner:
- Tjenester uten noen form for autorisering bĂžr ikke inneholde kritiske data for nettstedets drift. For eksempel, hvis du ikke har autorisasjon i ES â ville det vĂŠrt bedre Ă„ blokkere tilgang pĂ„ nettverksnivĂ„ fra alle steder der det ikke er nĂždvendig, og beholde bare de nĂždvendige, samt gjĂžre action.destructive_requires_name: true.
- Ăv pĂ„ mekanismen for sikkerhetskopiering og gjenoppretting pĂ„ forhĂ„nd. For eksempel, lag en skript (for eksempel i python) som kan bĂ„de sikkerhetskopiere og gjenopprette.
FĂžrsteplass â «Kapitano utydelighet»Â
PÄ et tidspunkt merket vi en ujevn belastning pÄ nginx upstreams nÄr backend hadde 10+ servere. Siden round-robin dirigerte forespÞrslene fra 1 til siste upstream i rekkefÞlge, og hver reload av nginx startet pÄ nytt, fikk de fÞrste upstreamene alltid flere forespÞrsel enn de andre. Som et resultat jobbet de tregere, og hele nettsiden led. Dette ble mer og mer merkbart etter hvert som trafikken Þkte. Det var ikke nok Ä bare oppdatere nginx for Ä aktivere random; vi mÄtte omskrive mye lua-kode som ikke fungerte pÄ versjon 1.15 (pÄ den tiden). Vi mÄtte patch nginx 1.14.2 for Ä legge til stÞtte for random. Dette lÞste problemet. Denne feilen vinner prisen for «kaptein Äpenbarhet».
Konklusjoner:
Det var veldig interessant og engasjerende Ă„ undersĂžke denne feilen).Â
- Sett opp overvĂ„kning slik at den kan hjelpe deg med Ă„ raskt finne slike fluktuasjoner. For eksempel kan man bruke ELK for Ă„ overvĂ„ke rps pĂ„ hver backend av hver upstream, og fĂžlge med pĂ„ svartidene gjennom nginx. I dette tilfellet hjalp det oss Ă„ avdekke problemet.Â
Mye av feilen kunne vĂŠrt unngĂ„tt med en mer grundig tilnĂŠrming til det man gjĂžr. Man mĂ„ alltid huske pĂ„ Murphyâs lov: Anything that can go wrong will go wrong, og bygge komponenter med dette i tankene.Â
Kilde: habr.com
