
Tere kĂ”igile!Â
Minu nimi on Nikita, olen ĐŠĐžĐ°Đœ'i insenerimeeskonna tiimijuht. Ăks minu ĂŒlesannetest firmas on vĂ€hendada produtseerimise infrastruktuuriga seotud intsidente nullini.
KĂ€esolevas artiklis kĂ€sitletav teema on meile palju valu toonud, ja eesmĂ€rk on vĂ€ltida, et teised inimesed kordaks meie vigu vĂ”i vĂ€hemalt minimeeriks nende mĂ”ju.Â
Eesliide
Kauges minevikus, kui ĐŠĐžĐ°Đœ koosnes monoliitidest ja mikroteenustest polnud veel jĂ€lgegi, mÔÔtsime ressursi kĂ€ttesaadavust kontrollides 3â5 lehte.Â
Kui nad vastavad â on kĂ”ik hĂ€sti, kui nad ei vasta pikka aega â on hĂ€ire. Kui kaua nad peavad mitte töötama, et seda loetaks intsidendiks, mÀÀrati koosolekutel. Insenerimeeskond osales alati intsidendi uurimises. Kui uurimine oli lĂ”petatud, kirjutati post mortem â omamoodi aruanne e-posti formaadis: mis juhtus, kui kaua see kestis, mida tehti hetkel, mida teeme tulevikus.Â
Peamised veebisaidi lehed vÔi kuidas me mÔistame, et oleme pÔhja tabanud
Â
Kuna me pĂŒĂŒame mĂ”ista vea prioriteeti, oleme vĂ€lja toonud kĂ”ige kriitilisemad veebisaidi lehed Ă€ritegevuse funktsionaalsuse jaoks. Nende pĂ”hjal loeme edukaid/ebaĂ”nnestunud pĂ€ringute ja ajakulu arvu. Nii mÔÔdame uptime'i.Â
Oletame, et oleme tuvastanud, et on olemas rida superolulisi veebisaidi sektsioone, mis vastutavad pĂ”hiteenuse â otsingu ja kuulutuste esitamise â eest. Kui veaga lĂ”ppenud pĂ€ringute arv ĂŒletab 1%, on see kriitiline intsident. Kui tipptunnil 15 minuti jooksul veaprotsent ĂŒletab 0,1%, loetakse seda samuti kriitiliseks intsidendiks. Need kriteeriumid katab suurema osa intsidendidest, teised jÀÀvad artikli raamesse.

ĐŠĐžĐ°Đœ'i parimate intsidentide edetabel
Nii et me oleme kindlasti Ă”ppinud tuvastama, et intsident on juhtunud.Â
NĂŒĂŒd on iga intsident detailselt kirjeldatud ja kajastatud Jira epic'is. Muide: selleks kĂ€ivitasime eraldi projekti, mille nimeks sai FAIL â seal saab luua ainult epikuid.Â
Kui koguda kokku kĂ”ik ebaĂ”nnestumised viimase paari aasta jooksul, siis valitsevad:Â
- intsidendid, mis on seotud mssql-iga;
- intsidendid, mis on tingitud vÀlistest teguritest;
- admini vead.
Haarame pÔhjalikumalt kinni adminide vigadest ja mÔnest muust huvitavast ebaÔnnestumisest.
Viies koht â 'Teeme korda DNS'i'
See oli sombune teisipĂ€ev. Otsustasime DNS-klastri korrastada.Â
Soovisime ĂŒmber seadistada sise dns-serverid bindilt powerdns-ile, eraldades selleks tĂ€ielikult eraldi serverid, kus peale dns-i midagi ei ole.Â
Paigutasime igasse meie andmekeskuse asukohta ĂŒhe dns-serveri ja saabus hetk, mil tegime tsoonide ĂŒleviimise bindilt powerdns-ile ning lĂŒlitasime infrastruktuuri uutele serveritele.Â
Ăleviimise kĂ”ige tihedamal perioodil jĂ€i meil alles vaid ĂŒks dns-server, serverid, mis oli kohalikes vahemĂ€lu bind-ides kĂ”igil serveritel, oli Peterburi andmekeskuses. See andmekeskus oli algselt deklareeritud meie jaoks mitte kriitiliseks, kuid muutus Ă€kitselt ĂŒhekordseks rikke kohaks.
Just selle ĂŒlemineku ajal kukkus kanal Moskva ja Peterburi vahel. Me olime tegelikult viie minuti jooksul DNS-ita ja saime uuesti tööle, kui hostija vead likvideeriti.Â
KokkuvÔtted:
Kui varem olime me vĂ€listest teguritest tööde ettevalmistamisel mööda vaadanud, siis nĂŒĂŒd oleme need ka ettevalmistuse nimekirja lisanud. Ja nĂŒĂŒd pĂŒĂŒame tagada, et kĂ”ik komponendid on reserveeritud n-2, ja tööde ajaks saame selle taseme langetada n-1.
- Tegevusplaani koostamisel mĂ€rkige ĂŒles punktid, kus teenus vĂ”ib kokku kukkuda, ja mĂ”elge lĂ€bi stsenaarium, kus kĂ”ik lĂ€heb halvasti, ette.
- Jaotage sise dns-serverid erinevatesse geolokatsioonidesse/andmekeskustesse/rakendustesse/lĂŒlititesse/sisenditesse.
- Iga serveri jaoks seadke ĂŒles lokaalset vahemĂ€lu dns-serverit, mis suunab pĂ€ringud peamistele dns-serveritele ning juhul, kui see ei ole saadaval, vastab vahemĂ€lust.Â
Neljas koht - "Korrastame Nginx'i"
Ăhel kenal pĂ€eval otsustas meie meeskond, et âpiisab sellest talumisestâ, ja algas nginx-i konfiguratsioonide refaktoreerimise protsess. Peamine eesmĂ€rk on tuua konfiguratsioonid intuitiivselt arusaadavasse struktuuri. Varem oli kĂ”ik olnud âajaloo tĂ”ttuâ ja loogikat ei olnud. NĂŒĂŒd on iga server_name viidatud sama nimega faili ja kĂ”ik konfiguratsioonid on jaotatud kaustadesse. Muide - konfiguratsioon sisaldab 253949 rida vĂ”i 7836520 mĂ€rki ja on peaaegu 7 megabaiti suur. Ălemise taseme struktuur:Â
Nginx struktuur
âââ access
â Â âââ allow.list
...
â Â âââ whitelist.conf
âââ geobase
â Â âââ exclude.conf
...
â Â âââ geo_ip_to_region_id.conf
âââ geodb
â Â âââ GeoIP.dat
â Â âââ GeoIP2-Country.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.confOn parem, kuid konfigureerimise ĂŒmbernimetamise ja jagamise kĂ€igus oli mitmel neist vale laiend ja nad ei sattunud direktiivi include *.conf. Selle tulemusena olid mĂ”ned hostid kĂ€ttesaamatud ja suunati 301 pĂ”hilehe poole. Kuna vastuskood ei olnud 5xx/4xx, mĂ€rkasime seda alles hommikul. PĂ€rast seda hakkasime kirjutama teste infrastruktuuri komponentide kontrollimiseks.
KokkuvĂ”tted:Â
- Struktureerige konfigureerimine Ôigesti (mitte ainult nginx) ja mÔelge struktuuri varajases projekti etapis. Nii teete need meeskonnale arusaadavamaks, mis omakorda vÀhendab TTM-i.
- Kirjutage mĂ”ne infrastruktuuri komponendi jaoks teste. NĂ€iteks: kontrollige, et kĂ”ik olulised server_name tagastavad Ă”ige staatuse ja vastuse keha. Piisab, kui teil on lihtsalt paar skripti, mis kontrollivad komponendi pĂ”hifunktsioone, et mitte 3 öösel pĂ”hjalikult mĂ”elda, mida veel kontrollida.Â
Kolmas koht â "ĂhtĂ€kki lĂ”ppes koht Cassandra's"
Andmed kasvasid jĂ€rk-jĂ€rgult ja kĂ”ik oli hĂ€sti, kuni Cassandra klastris hakkasid kukkuma repair suurtel keyspace'idel, kuna compaction ei saanud töötada.Â
Ăhel sombusel pĂ€eval muutus klaster peaaegu kĂ”rvitsaks, nimelt:
- koha jÀi klastrisse umbes 20%;
- tÀielikult node'e lisada ei saa, kuna node'i lisamise jÀrel ei toimu cleanup-i ruumi puudumise tÔttu partitsioonides;
- tootlikkus langeb tasapisi, kuna compaction ei toimi;Â
- klaster töötab avariireĆŸiimis.

VĂ€ljund â lisasime veel 5 sĂ”lme ilma puhastuseta, pĂ€rast mida hakkasime jĂ€rk-jĂ€rgult klastrist eemaldama ja uuesti lisama, nagu tĂŒhjad sĂ”lmed, millel ruum lĂ”ppes. Aega on kulutatud oluliselt rohkem, kui oleks soovinud. Oli oht osalise vĂ”i tĂ€ieliku klastrite kĂ€ttesaamatuse osas.Â
KokkuvÔtted:
- KĂ”ikidel cassandra serveritel ei tohi iga jaotuse peal olla rohkem kui 60% ruumi kasutuses.Â
- Need ei tohi olla laaditud rohkem kui 50% CPU-st.
- Ărge unustage mahtude planeerimist ja seda tuleks mĂ”elda iga kompoondi suhtes, lĂ€htudes tema spetsiifikast.
- Mida rohkem sĂ”lmi klastris, seda parem. Serverid, mis sisaldavad vĂ€ikest andmemahu, laaditakse kiiremini ja sellist klastrit on lihtsam taastada.Â
Teine koht â âAndmed kadusid consul key-value salvestusestâ
Teenuste avastamiseks kasutame nagu paljud teisedki consul. Kuid meil kasutatakse tema key-value veel ka monoliidi blue-green vĂ€lja laskmiseks. Seal hoitakse teavet aktiivsete ja mitteaktiivsete upstreamide kohta, mis vahetavad kohti juurutamise ajal. Selleks kirjutati juurutamise teenus, mis suhtles KV-ga. Ăhel hetkel kadusid andmed KV-st. Taastasime mĂ€lust, kuid mitmete vigadega. TagajĂ€rjena jaotati koormus upstreamidele ebaĂŒhtlaselt ja saime palju 502 vigu, kuna backendide CPU oli ĂŒle koormatud. LĂ”ppkokkuvĂ”ttes kolisime consul KV-lt postgres'i, kust nende eemaldamine ei ole enam nii lihtne. Â
KokkuvÔtted:
- Teenused, millel ei ole mingit autoriseerimist, ei tohi sisaldada veebisaidi toimimiseks kriitilisi andmeid. NĂ€iteks, kui teil ei ole autoriseerimist ES-is â oleks parem keelata juurdepÀÀs vĂ”rgu tasemel kĂ”ikjal, kus see ei ole vajalik, jĂ€tta alles ainult vajalikud, ning seada action.destructive_requires_name: true.
- Harjutage varukoopiate ja taastamise mehhanismi eelnevalt. NÀiteks kirjutage ette skript (nÀiteks pythonis), mis oskab nii varundada kui ka taastada.
Esimene koht â âKapten ebaselgusâÂ
Mingil hetkel mĂ€rkamisime, et nginx'i ĂŒlesvoolude koormus oli ebaĂŒhtlaselt jaotunud, kui tagaplaanil oli rohkem kui 10 serverit. Kuna round-robin suunas pĂ€ringud esimesest kuni viimase ĂŒlesvooluni jĂ€rjestikku ja iga nginx'i uuendamine algas algusest, said esimesed ĂŒlesvoolud alati rohkem pĂ€ringuid kui teised. Selle tulemusena töötasid nad aeglasemalt ja kogu veebisait kannatas. See muutus ĂŒha silmatorkavamaks, kui liiklus suurenes. Lihtne nginx'i vĂ€rskendamine random'i toeks ei piisand â pidime ĂŒmber tegema hulga lua koodi, mis versioonil 1.15 ei töötanud (selles hetkes). Me pidime patĆĄima meie nginx 1.14.2, lisades sellele random'i toe. See lahendas probleemi. See bugi vĂ”idab âkapteni ebaselgusâ auhinna.
KokkuvÔtted:
See oli vĂ€ga huvitav ja kaasahaarav uurida seda viga).Â
- Seadke jĂ€lgimine ĂŒles nii, et see aitaks kiiresti leida sarnaseid fluctuaatsioone. NĂ€iteks vĂ”ib kasutada ELK-d, et jĂ€lgida rps-i iga tagaplaani jaoks iga ĂŒlesvoolu puhul ning jĂ€lgida nende vastusaega nginx'i kontekstis. Sel juhul aitas see meil probleemi tuvastada.Â
Suurema osa ebaĂ”nnestumisi oleks saanud vĂ€ltida, kui oleksime lĂ€henenud asjadele pĂ”hjalikumalt. Peame alati meeles pidama Murphy seadust: Anything that can go wrong will go wrong, ja ehitama komponente, lĂ€htudes sellest.Â
Allikas: habr.com
