
MirĂ«si pĂ«r tĂ« gjithĂ«!Â
Më quajnë Nikita, unë jam lideri i ekipit të inxhinierëve në Cian. Një nga detyrat e mia në kompani është të reduktoj ngjarjet që lidhen me infrastrukturën në prodhim, deri në zero.
Ajo qĂ« do tĂ« diskutohet mĂ« poshtĂ« na ka sjellĂ« shumĂ« dhimbje, dhe qĂ«llimi i kĂ«tij artikulli Ă«shtĂ« tĂ« mos lejojmĂ« qĂ« tĂ« tjerĂ«t tĂ« pĂ«rsĂ«risin gabimet tona ose tĂ« paktĂ«n tĂ« minimalizojnĂ« ndikimin e tyre.Â
Preambula
KohĂ« mĂ« parĂ«, kur Cian ishte njĂ« monolit dhe nuk kishte asnjĂ« shenjĂ« tĂ« mikroshĂ«rbimeve, ne matnim disponueshmĂ«rinĂ« e burimit duke kontrolluar 3â5 faqe.Â
NĂ«se pĂ«rgjigjen - gjithçka Ă«shtĂ« nĂ« rregull, dhe nĂ«se nuk pĂ«rgjigjen pĂ«r njĂ« kohĂ« tĂ« gjatĂ« - alarĂ«m. Sa kohĂ« duhet tĂ« mos funksionojnĂ« pĂ«r ta konsideruar si njĂ« ngjarje, e vendosnin njerĂ«zit nĂ« mbledhje. Ekipi i inxhinierĂ«ve gjithmonĂ« merrte pjesĂ« nĂ« hetimin e ngjarjes. Kur hetimi pĂ«rfundonte, shkruanin njĂ« postmortem - njĂ« raport tĂ« veçantĂ« qĂ« dĂ«rgohej me email nĂ« format: çfarĂ« ndodhi, sa zgjati, çfarĂ« bĂ«mĂ« nĂ« momentin e ngjarjes, çfarĂ« do tĂ« bĂ«jmĂ« nĂ« tĂ« ardhmen.Â
Faqet kryesore të faqes ose si kuptojmë se e kemi arritur fundin
Â
PĂ«r tĂ« kuptuar siç duhet pĂ«rparĂ«sinĂ« e gabimeve, ne kemi identifikuar faqet mĂ« kritike pĂ«r funksionalitetin e biznesit. PĂ«r to, ne llogarisim numrin e kĂ«rkesave tĂ« sukseshme/dĂ«shtuar dhe kohĂ«zgjatjet. KĂ«shtu masim uptime-in.Â
Le të themi se kemi zbuluar se ekzistojnë disa seksione super të rëndësishme të faqes që janë përgjegjëse për shërbimin kryesor - kërkimi dhe paraqitja e shpalljeve. Nëse numri i kërkesave që përfunduan me gabim kalon 1% - është një ngjarje kritike. Nëse brenda 15 minutash në orar të pikut përqindja e gabimeve kalon 0,1% - atëherë kjo gjithashtu konsiderohet si një ngjarje kritike. Këto kritere mbulojnë pjesën më të madhe të ngjarjeve, të tjera dalin jashtë këtij artikulli.

Top ngjarjet më të mira të Cian
Pra, ne me siguri kemi mĂ«suar tĂ« pĂ«rcaktojmĂ« faktin qĂ« ka ndodhur njĂ« ngjarje.Â
Tani çdo ngjarje Ă«shtĂ« e pĂ«rshkruar nĂ« detaje dhe pasqyrohet nĂ« epikĂ«n Jira. PĂ«r ta thĂ«nĂ« kĂ«tĂ«: pĂ«r kĂ«tĂ« ne nisĂ«m njĂ« projekt tĂ« veçantĂ« dhe e quajtĂ«m FAIL - nĂ« tĂ« mund tĂ« krijohet vetĂ«m epikĂ«.Â
NĂ«se mbledhim tĂ« gjitha dĂ«shtimet e vitet e fundit, ato kryesojnĂ«:Â
- ngjarjet që lidhen me mssql;
- ngjarjet që u shkaktuan nga faktorë të jashtëm;
- gabimet e administratës.
Do të përqendrohemi më në detaje në gabimet e administratorëve, si dhe në disa dështime të tjera interesante.
Vendi i pestë - "Renditja e DNS-it"
Ishte njĂ« martĂ« e ndotur. VendosĂ«m tĂ« rregullojmĂ« rendin nĂ« DNS-klusterin tonĂ«.Â
U dĂ«shiruam tĂ« kalonim serverat e brendshĂ«m DNS nga bind nĂ« powerdns, duke rezervuar pĂ«r kĂ«tĂ« servera krejtĂ«sisht tĂ« veçantĂ«, ku nuk ka asgjĂ« tjetĂ«r pĂ«rveç DNS.Â
VendosĂ«m nga njĂ« server DNS nĂ« çdo vendndodhje tĂ« qendrave tona tĂ« tĂ« dhĂ«nave, dhe erdhi momenti i kalimit tĂ« zonave nga bind nĂ« powerdns dhe kalimin e infrastrukturĂ«s nĂ« serverat e rinj.Â
Në kulmin e kalimit nga të gjitha serverësh, që ishin shënuar në cache-local bind në të gjitha serverat, mbeti vetëm një, që ishte në qendrën e të dhënave në Shën Petersburg. Ky DC në fillim ishte deklaruar si jo kritik për ne, por papritmas u bë një pikë e vetme dështimi.
PikĂ«risht nĂ« kĂ«tĂ« periudhĂ« kalimi ra lidhja midis MoskĂ«s dhe ShĂ«n Petersburgut. NĂ« fakt, mbetĂ«m pa DNS pĂ«r pesĂ« minuta dhe u rikthyem, kur hosti zgjidhi problemet.Â
Përfundimet:
Nëse më parë e neglizhonim faktorët e jashtëm gjatë përgatitjes për punë, tani i përfshimë ato në listën e asaj për të cilën po përgatitemi. Dhe tani synojmë që të gjithë komponentët të jenë të rezervuar n-2, ndërsa gjatë punëve mund të ulim këtë nivel në n-1.
- Gjatë hartimit të planit të veprimit, shënoni pikat ku shërbimi mund të bjerë, dhe mendoni për skenarin ku gjithçka shkon "më keq se asnjëherë" paraprakisht.
- Rregulloni serverat e brendshëm DNS në lokacione të ndryshme gjeografike/qendra të të dhënave/rrafshina/switch-e/influx.
- NĂ« çdo server vendosni njĂ« server lokal tĂ« cache DNS, i cili redirekton kĂ«rkesat nĂ« serverat kryesorĂ« tĂ« DNS, dhe nĂ« rast tĂ« papĂ«rshtatshmĂ«risĂ« do tĂ« pĂ«rgjigjet nga cache.Â
Vendi i katĂ«rt â "RregullojmĂ« rregullat nĂ« Nginx"
NĂ« njĂ« ditĂ« tĂ« bukur, ekipi ynĂ« vendosi se "mjafton tĂ« durojmĂ«", dhe procesi i riorganizimit tĂ« konfigurimeve tĂ« nginx filloi. QĂ«llimi kryesor â tĂ« sjellim konfigurimet nĂ« njĂ« strukturĂ« intuitivisht tĂ« kuptueshme. MĂ« parĂ« gjithçka ishte "historikisht e krijuar" dhe nuk kishte logjikĂ«. Tani çdo server_name Ă«shtĂ« nxjerrĂ« nĂ« njĂ« skedar tĂ« quajtur nĂ« tĂ« njĂ«jtĂ«n emĂ«r dhe tĂ« gjitha konfigurimet janĂ« shpĂ«rndarĂ« nĂ« dosje. PĂ«r t'u thĂ«nĂ« â konfigurimi pĂ«rmban 253949 rreshta ose 7836520 karaktere dhe zĂ« pothuajse 7 megabajt. Niveli i sipĂ«rm i strukturĂ«s:Â
Struktura e Nginx
âââ akses
â Â âââ 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
...
â Â âââ dinamik
â Â âââ 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.confKa ishte shumĂ« mĂ« mirĂ«, por gjatĂ« procesit tĂ« rinomimit dhe shpĂ«rndarjes sĂ« konfigurations, disa prej tyre kishin njĂ« zgjerim tĂ« gabuar dhe nuk u futĂ«n nĂ« direktivĂ«n include *.conf. Si pasojĂ«, disa hoste u bĂ«nĂ« tĂ« paqĂ«ndrueshĂ«m dhe kthyen 301 nĂ« kryefaqe. PĂ«r shkak se kodi i pĂ«rgjigjes nuk ishte 5xx/4xx, kĂ«tĂ« nuk e vunĂ« re menjĂ«herĂ«, por vetĂ«m nĂ« mĂ«ngjes. Pas kĂ«saj, filluam tĂ« shkruajmĂ« teste pĂ«r kontrollet e komponenteve infrastrukturore.
PĂ«rfundimet:Â
- Strukturoni me saktĂ«si konfigurat (jo vetĂ«m nginx) dhe mendoni pĂ«r strukturĂ«n nĂ« fazĂ«n fillestare tĂ« projektit. KĂ«shtu do tâi bĂ«ni ato mĂ« tĂ« kuptueshme pĂ«r ekipin, çka nga ana tjetĂ«r do tĂ« ulĂ« TTM-nĂ«.
- PĂ«r disa komponente infrastrukturore shkruani teste. PĂ«r shembull: kontrolloni qĂ« tĂ« gjithĂ« server_name kyç tâi japin statusin e duhur, + trupin e pĂ«rgjigjes. Mjafton tĂ« keni disa skripte qĂ« kontrollojnĂ« funksionet kryesore tĂ« komponentit, nĂ« mĂ«nyrĂ« qĂ« tĂ« mos kujtoni me panik nĂ« 3 tĂ« mĂ«ngjesit çfarĂ« duhet tĂ« kontrolloni.Â
Vendi i tretĂ« â "Papritur mbaroi vendi nĂ« Cassandra"
TĂ« dhĂ«nat rriteshin rregullisht, dhe gjithçka ishte mirĂ« deri nĂ« momentin kur nĂ« klasterin Cassandra filluan tĂ« dĂ«shtojnĂ« riparimet e case-space-ve tĂ« mĂ«dha, sepse nuk mund tĂ« funksiononte kompaktimi.Â
Në një ditë të errët, klasteri u shndërrua pothuajse në një kungull, konkretisht:
- mbetën rreth 20% e përgjithshme për klasterin;
- nuk mund të shtohen nodet në mënyrë të plotë, sepse nuk kalon pastrimin pas shtimit të nodit për shkak të mungesës së vendit në seksionet;
- performanca po ulet ngadalĂ«, pasi kompaktimi nuk punon;Â
- klasteri punon në një modalitet emergjent.

Ixit â kemi shtuar edhe 5 nodĂ« pa pastrimin, pas tĂ« cilave filluam ta nxjerrim gradualisht nga klasteri dhe ta rikthejmĂ« pĂ«rsĂ«ri, si nodĂ« tĂ« pastra, nĂ« tĂ« cilat kishte pĂ«rfunduar hapĂ«sira. Koha e shpenzuar Ă«shtĂ« shumĂ« mĂ« e madhe se sa do tĂ« doja. Ishte njĂ« rrezik i disponueshmĂ«risĂ« pjesore ose tĂ« plotĂ« tĂ« klasterit.Â
Përfundimet:
- NĂ« tĂ« gjitha serverat cassandra, hapĂ«sira nĂ« secilin seksion nuk duhet tĂ« jetĂ« mĂ« shumĂ« se 60%.Â
- Të ngarkuarit nuk duhet të jenë më shumë se 50% për CPU.
- Nuk duhet të neglizhohet planifikimi i kapacitetit dhe ai duhet menduar për secilin komponent, në bazë të specifikave të tij.
- Sa mĂ« shumĂ« nodĂ« tĂ« jenĂ« nĂ« klaster, aq mĂ« mirĂ«. Serverat qĂ« mbajnĂ« njĂ« volum tĂ« vogĂ«l tĂ« tĂ« dhĂ«nave janĂ« mĂ« tĂ« shpejtĂ« nĂ« rikthim, dhe njĂ« klaster i tillĂ« Ă«shtĂ« mĂ« i lehtĂ« pĂ«r t'u ringjallur.Â
Vendi i dytĂ« â âTĂ« dhĂ«nat u zhdukĂ«n nga konsoli i ruajtjes key-value.â
PĂ«r zbulimin e shĂ«rbimeve, ne, ashtu si shumĂ« tĂ« tjerĂ«, pĂ«rdorim konsolĂ«n. Por KV i saj pĂ«rdoret gjithashtu pĂ«r shpĂ«rndarjen blue-green tĂ« monolit. Atje ruhet informacioni mbi upstream-et aktiv dhe jo aktiv, tĂ« cilĂ«t ndĂ«rruan vende gjatĂ« deplojit. PĂ«r kĂ«tĂ«, Ă«shtĂ« shkruar njĂ« shĂ«rbim deploy-i, qĂ« ndĂ«rvepronte me KV. NĂ« njĂ« moment, tĂ« dhĂ«nat nga KV u humbĂ«n. U rikuperuan nga memoria, por me disa gabime. Si pasojĂ«, gjatĂ« shpĂ«rndarjes, ngarkesa nĂ« upstream ishte e shpĂ«rndarĂ« nĂ« mĂ«nyrĂ« tĂ« pabarabartĂ«, dhe ne morĂ«m shumĂ« gabime 502 pĂ«r shkak tĂ« ngarkesĂ«s nĂ« backend pĂ«r CPU. NĂ« fund, u transferuam nga konsolĂ« KV nĂ« postgres, nga e cila Ă«shtĂ« mĂ« e vĂ«shtirĂ« pĂ«r t'i fshirĂ« tashmĂ«. Â
Përfundimet:
- ShĂ«rbimet pa ndonjĂ« autorizim nuk duhet tĂ« pĂ«rmbajnĂ« tĂ« dhĂ«na kritike pĂ«r funksionimin e faqes. PĂ«r shembull, nĂ«se nuk keni autorizim nĂ« ES â do tĂ« ishte mĂ« mirĂ« tĂ« ndalonit qasje nĂ« nivelin e rrjetit nga çdo vend qĂ« nuk Ă«shtĂ« e nevojshme, tĂ« lini vetĂ«m ato tĂ« nevojshme, dhe gjithashtu tĂ« bĂ«ni action.destructive_requires_name: true.
- Punoni për mekanizmin e rezervës dhe rikuperimit paraprakisht. Për shembull, krijoni një skenar (për shembull, në python), që di të bëjë backup dhe rikthim.
Vendi i parĂ« â âKapiteni i paqartĂ«sisĂ«.âÂ
NĂ« njĂ« moment, ne vĂ«mĂ« re njĂ« shpĂ«rndarje tĂ« pandershme tĂ« ngarkesĂ«s nĂ« upstream-et e nginx nĂ« rastet kur nĂ« backend kishte 10+ serverĂ«. PĂ«r shkak se round-robin drejtonte kĂ«rkesat nga 1 nĂ« upstream-in e fundit me radhĂ«, dhe çdo rinovim i nginx fillonte nga e para, gjithmonĂ« kishte mĂ« shumĂ« kĂ«rkesa pĂ«r upstream-et e parĂ« sesa pĂ«r tĂ« tjerĂ«t. Si pasojĂ«, ata punonin mĂ« ngadalĂ« dhe tĂ« gjithĂ« u ndikuan nga kjo. Kjo bĂ«hej gjithnjĂ« e mĂ« e dukshme me rritjen e sasisĂ« sĂ« trafikut. NjĂ« thjeshtĂ« azhurnim nĂ« nginx pĂ«r tĂ« aktivizuar random nuk e zgjidhi problemin â duhej tĂ« rregullohej shumĂ« kod LUA, i cili nuk λΔÎčÏÎżÏ ÏÎłonte nĂ« versionin 1.15 (nĂ« atĂ« kohĂ«). Iu desh tĂ« patchonim nginx 1.14.2 tonin, duke futur mbĂ«shtetje pĂ«r random. Kjo e zgjidhi problemin. Ky defekt Ă«shtĂ« fitues nĂ« kategorinĂ« «kapitani i padukshmĂ«risë».
Përfundimet:
Ishte shumĂ« interesante dhe emocionuese tĂ« hetoja kĂ«tĂ« defekt).Â
- NdĂ«rtoni monitorimin nĂ« mĂ«nyrĂ« qĂ« ai tĂ« ndihmojĂ« nĂ« gjetjen e fluktuacioneve tĂ« tilla shpejt. PĂ«r shembull, mund tĂ« pĂ«rdorni ELK pĂ«r tĂ« vĂ«zhguar rps pĂ«r çdo backend tĂ« çdo upstream, duke ndjekur kohĂ«n e tyre tĂ« pĂ«rgjigjes nga perspektiva e nginx. NĂ« kĂ«tĂ« rast, kjo na ndihmoi tĂ« identifikohemi problemin.Â
Si rezultat, shumĂ« prej dĂ«shtimeve do tĂ« ishin shmangur me njĂ« qĂ«ndrim mĂ« tĂ« kujdesshĂ«m nĂ« ato qĂ« bĂ«ni. Duhet gjithmonĂ« tĂ« mbani mend ligjin e Murphy: Ădo gjĂ« qĂ« mund tĂ« shkojĂ« keq do tĂ« shkojĂ« keq, dhe tĂ« ndĂ«rtoni komponente duke u udhĂ«hequr nga ajo.Â
Burimi: habr.com
