Dërgimi i një versioni të ri të projektit në prodhim kërkon një balancim të kujdesshëm midis shpejtësisë së implementimit dhe besueshmërisë së zgjidhjes. Në kompaninë Slack, vlerësohen iteracionet e shpejta, ciklet e shkurtra të feedback-ut dhe reagimi i shpejtë ndaj kërkesave të përdoruesve. Për më tepër, kompania ka qindra programues që përpiqen të arrijnë produktivitetin maksimal.
Autorët e materialit, përkthimi i të cilit po publikojmë sot, thonë se një kompani që përpiqet të respektojë këto vlera dhe njëkohësisht të rritet, duhet të përmirësojë vazhdimisht sistemin e saj të implementimit të projekteve. Kompania duhet të investojë për transparencën dhe besueshmërinë e proceseve të punës, duke e bërë këtë që ato të përputhen me shkallën e projektit. Ky artikull do të flasë për proceset e punës të ngritura në Slack dhe për disa zgjidhje që çuan kompaninë në përdorimin e sistemit aktual të implementimit të projekteve.
Si funksionojnë sot proceset e implementimit të projekteve
Çdo PR (pull request) në Slack duhet të kalojë me detyrim një rishikim të kodit dhe të kalojë me sukses të gjitha testet. Vetëm pasi të përmbushen këto kushte, programuesi mund të realizojë bashkimin e kodit të tij me degën master të projektit. Megjithatë, implementimi i këtij kodi realizohet vetëm gjatë orëve të punës sipas kohës së Amerikës së Veriut. Si rezultat, për shkak se punonjësit tanë janë në vendin e punës, jemi plotësisht të gatshëm të zgjidhim çfarëdo problemi të papritur.
Çdo ditë realizojmë rreth 12 implementime të planifikuara. Gjatë çdo implementimi, programuesi i caktuar si përgjegjës për implementimin, është përgjegjës për dërgimin e një ndërtese të re në prodhim. Ky është një proces me shumë hapa që siguron një kalim të qetë të ndërtimit në statusin e punës. Falë këtij qasje, mund të zbulojmë gabimet përpara se ato të ndalojnë përdoruesit tanë të gjithë. Nëse gabimet janë tepër të shumta - implementimi i ndërtimit mund të kthehet mbrapa. Megjithatë, nëse ndonjë problem i veçantë zbulohet pas lëshimit, për të mund të lëshohet një rregullim i lehtë.

Ndërfaqja e sistemit Checkpoint, e cila përdoret në Slack për implementimin e projekteve
Procesi i implementimit të një versioni të ri në prodhim mund të paraqitet në katër hapa.
▍1. Krijimi i degës së versionit
Çdo version fillon me një degë të re versioni, nga një moment në historinë tonë Git. Kjo lejon që t'i caktohen etiketa versionit dhe ofron një vend ku mund të bëhen rregullime të shpejta për gabimet e gjetura gjatë përgatitjes së versionit për lëshim në prodhim.
▍2. Implementimi në ambientin e ndërmjetëm
Hapi tjetër është implementimi i ndërtimit në serverët ndërmjetës (staging) dhe ekzekutimi i testit automatik për funksionalitetin e përgjithshëm të projektit (smoke test). Ambienti ndërmjetës është një ambient prodhimi, në të cilin nuk hyn trafiku i jashtëm. Në këtë ambient realizojmë testimin manual shtesë. Kjo na jep siguri të shtuar se projekti i ndryshuar funksionon siç duhet. Vetëm testet automatike nuk janë të mjaftueshme për të arritur një siguri të tillë.
▍3. Implementimi në ambientet dogfood dhe canary
Implementimi në prodhim fillon me ambientin dogfood, i përfaqësuar nga një grup hostesh që shërbejnë për hapësirat tona të punës të brendshme në Slack. Duke qenë se jemi përdorues shumë aktivë të Slack, ky qasje na ndihmoi të zbulojmë shumë gabime në fazat e hershme të implementimit. Pas sigurisë se funksionaliteti themelor i sistemit nuk është prishur, realizohet implementimi i ndërtimit në ambientin canary. Ky ambient përfaqëson sistemet në të cilat kalon rreth 2% të trafikut prodhimor.
▍4. Nxjerrja e ngadaltë në prodhim
Nëse treguesit e monitorimit të versionit të ri janë të qëndrueshëm, dhe nëse pas implementimit në ambientin canary nuk kemi marrë ankesa, ne vazhdojmë me kalimin e ngadaltë të serverëve prodhues në versionin e ri. Procesi i implementimit është i ndarë në hapat e mëposhtëm: 10%, 25%, 50%, 75% dhe 100%. Si rezultat, mund të transferojmë ngadalë trafikun prodhimor në versionin e ri të sistemit. Në të njëjtën kohë, kemi kohë për të shqyrtuar situatën në rast të zbulesave të ndonjë anomalie.
▍Çfarë të bëni nëse gjatë implementimit diçka ka shkuar keq?
Modifikimi i kodit gjithmonë paraqet një rrezik. Por ne e menaxhojmë këtë falë disponimit të mirë të "ekspertëve të implementimeve", të cilët drejtojnë procesin e publikimit të versionit të ri në prodhim, ndjekin metriken e monitorimit dhe koordinojnë punën e programuesve që publikojnë kodin.
Në rastin kur diçka vërtet ka shkuar keq, ne përpiqemi ta zbulojmë problemin sa më shpejt të jetë e mundur. Ne e shqyrtojmë problemin, gjejmë PR-në që shkakton gabime, e rroktojmë atë, e analizojmë me kujdes dhe krijojmë një ndërtim të ri. Megjithatë, herë pas here problemi mbetet i padukshëm deri në publikimin e projektit në prodhim. Në një situatë të tillë, e rëndësishme është rikthimi i funksionimit të shërbimit. Prandaj, përpara se të fillojmë hetimin e problemit, ne menjëherë rikthehemi në ndërtimin e mëparshëm që funksiononte.
Blloqet ndërtuese të sistemit të implementimit
Le të shqyrtojmë teknologjitë që qëndrojnë pas sistemit tonë të implementimit të projekteve.
▍Implementime të shpejta
Procesi i punës i përshkruar më sipër mund të duket në retrospektivë si diçka krejtësisht e qartë. Por sistemi ynë i implementimit nuk u bë kështu menjëherë.
Kur kompania ishte shumë më e vogël, të gjithë aplikacioni ynë mund të funksiononte në 10 instancat Amazon EC2. Implementimi i projektit në një situatë të tillë do të thoshte të përdorim rsync për të sinkronizuar shpejt të gjitha serverat. Më parë, kodi i ri ndante vetëm një hap nga prodhimi, i përfaqësuar nga një ambient ndërmjetës. Ndërtimet krijoheshin dhe shqyrtoheshin në atë ambient dhe pastaj shkonin menjëherë në prodhim. Të kuptosh një sistem të tillë ishte shumë e thjeshtë; ai lejonte çdo programues që në çdo kohë të implementonte kodin e shkruar prej tij.
Por ndërsa numri i klientëve tanë rritej, po ashtu edhe përmasat e infrastrukturës së nevojshme për të mbështetur funksionimin e projektit. Shpejt, duke marrë parasysh rritjen e vazhdueshme të sistemit, modeli ynë i implementimit, i bazuar në dërgimin e kodit të ri në servera, nuk ishte më në gjendje të përballonte detyrat e tij. Kjo ndodhte sepse çdo server i ri do të thoshte një rritje të kohës së nevojshme për të implementuar. Edhe strategjitë, të bazuara në implementimin paralel të rsync, kanë kufizime të caktuara.
Në fund, ne e zgjidhëm këtë problem duke kaluar në një sistem të plotë paralel të implementimit, i cili nuk ishte si sistemi i vjetër. Tani ne nuk e dërgonim kodin në servera duke përdorur një skenar sinkronizimi. Tani çdo server ngarkohej vetë me ndërtimin e ri, duke mësuar se ishte koha për ta bërë këtë përmes vëzhgimit të ndryshimit të çelësit Consul. Serverat ngarkonin kodin paralelisht. Kjo na lejoi të mbajmë një shpejtësi të lartë implementimi, edhe në një mjedis rritjeje të vazhdueshme të sistemit.

1. Serverat në prodhim monitorojnë çelësin Consul. 2. Çelësi ndryshon, duke informuar serverat që të fillojnë ngarkimin e kodit të ri. 3. Serverat ngarkojnë skedarët tarball me kodin e aplikacionit.
▍Implementime atomike
Një zgjidhje tjetër që na ndihmoi të arrijmë një sistem multistages të implementimit ishte implementimi atomic.
Para se të fillonim implementimet atomike, çdo implementim mund të shkaktonte një shumëllojshmëri të madhe të mesazheve gabim. Arsyeja është se procesi i kopjimit të skedarëve të rinj në serverat e prodhimit nuk ishte atomic. Kjo çonte në ekzistencën e një intervali të shkurtër kohor, kur kodi që thërriste funksionet e reja ishte i disponueshëm para se këto funksione vetë të ishin të aktivizuara. Kur një kod i tillë thirrej, kjo shkaktonte kthimin e gabimeve të brendshme. Kjo shfaqej në kërkesat e dështuara për API dhe në faqet e internetit "të prishura".
Ekipi që merrej me këtë problem e zgjidhi atë duke futur konceptet e direktive "të ngrohta" (hot) dhe "të ftohta" (cold). Kodi në direktivën "të ngrohtë" është përgjegjës për përpunimin e trafikut të prodhimit. Ndërsa në direktivat "të ftohta", kodi, gjatë funksionimit të sistemit, përgatitet vetëm për përdorim. Gjatë implementimit, kodi i ri kopjohej në një direktivë "të ftohtë" të papërdorur. Pastaj, kur në server nuk ka më procese aktive, bëhet një kalim i menjëhershëm në direktivën tjetër.

1. Zbërthimi i kodit të aplikacionit në direktivë "të ftohtë". 2. Kalimi i sistemit në direktivën "të ftohtë", e cila bëhet "të ngrohtë" (operacion atomic).
Përmbledhja: fokusimi në besueshmëri
Në vitin 2018, projekti arriti një shkallë të tillë sa që shpërndarjet shumë të shpejta filluan të dëmtojnë stabilitetin e produktit. Ne kishim një sistem të avancuar shpërndarjeje, në të cilin kishim investuar shumë forcë dhe kohë. Na duhej vetëm të ristrukturojmë dhe përmirësojmë proceset e organizimit të shpërndarjes. U bëmë një kompani mjaft të madhe, zhvillimet e së cilës përdoren në të gjithë botën për të mundësuar komunikim të pandërprerë dhe për të trajtuar probleme të rëndësishme. Prandaj, besueshmëria u bë qendra e vëmendjes sonë.
Na duheshin të bënim procesin e shpërndarjes së versioneve të reja të Slack më të sigurta. Kjo nevojë na çoi në përmirësimin e sistemit tonë të shpërndarjes. Në thelb, ne e diskutuam këtë sistem të avancuar më lart. Në thellësitë e sistemit, ne vazhdojmë të përdorim teknologjitë e shpërndarjes të shpejtë dhe atomike. Ndryshoi mënyra se si realizohet shpërndarja. Sistemi ynë i ri është i destinuar për realizimin gradual të shpërndarjes së kodit të ri në nivele të ndryshme, në mjedise të ndryshme. Tani ne përdorim mjete mbështetëse dhe mjete monitorimi më të avancuara se më parë. Kjo na jep mundësinë të kapim dhe të rregullojmë gabimet shumë para se ato të kenë mundësinë të arrijnë te përdoruesi fundor.
Por ne nuk planifikojmë të ndalemi këtu. Ne vazhdojmë ta përmirësojmë këtë sistem duke aplikuar mjete mbështetëse dhe mjete automatizimi më të avancuara.
Të nderuar lexues! Si funksionon procesi i shpërndarjes së versioneve të reja të projekteve aty ku punoni ju?
Burimi: habr.com
