Alates 2019. aastast kehtib Venemaal kohustusliku mĂ€rgistamise seadus. Seadus ei kehti kĂ”igi kaupade rĂŒhmade kohta ning kohustusliku mĂ€rgistamise jĂ”ustumise tĂ€htajad erinevatele kaugroupadele on erinevad. Esmalt kuuluvad kohustuslikule mĂ€rgistamisele tubakas, jalatsid, ravimid, hiljem lisanduvad ka teised tooted, nĂ€iteks parfĂŒĂŒmid, tekstiil ja piim. See seadusandlik uuendus on kĂ€ivitanud uute IT-lahenduste vĂ€ljatöötamise, mis vĂ”imaldavad jĂ€lgida kauba eluiga tootmisest kuni lĂ”pptarbijani, kĂ”ikide protsessis osalejate jaoks: nii riik kui ka kĂ”ik organisatsioonid, kes mĂŒĂŒvad kohustusliku mĂ€rgistamisega kaupu.
X5-s sai sĂŒsteem, mis jĂ€lgib mĂ€rgistatud kaupu ja vahetab andmeid riigi ja tarnijatega, nimeks "Markus". RÀÀgime jĂ€rjestikku, kuidas ja kes seda arendas, milline on tema tehnoloogia toetav struktuur ja miks meil on pĂ”hjust uhkust tunda.

Reaalne HighLoad
"Markus" lahendab mitmeid ĂŒlesandeid, peamine neist on integratsioonitegevus X5 teabelehtede ja riikliku mĂ€rgistatud toodete teabe sĂŒsteemi (GIS MP) vahel, et jĂ€lgida mĂ€rgistatud toodete liikumist. Lisaks salvestab platvorm kĂ”ik meile laekunud mĂ€rgistuskoodid ja nende koodide liikumise ajalugu objekte pidi, aitab kĂ”rvaldada mĂ€rgistatud toodete valejaotuse. NĂ€iteks tubakatoodete osas, mis kuulusid esimesse mĂ€rgistatud kaupade rĂŒhma, sisaldab ĂŒks kaubik sigarette umbes 600 000 pakki, millest igaĂŒhel on oma ainulaadne kood. Ja meie sĂŒsteemi ĂŒlesanne on jĂ€lgida ja kontrollida iga sellise paki seaduslikkust liikumise osas ladude ja poodide vahel, ning lĂ”puks kontrollida, kas nende mĂŒĂŒk lĂ”pptarbijale on lubatud. Kassatehingute puhul fikseerime umbes 125 000 tunni kohta ning tuleb veel fikseerida ka see, kuidas iga selline pakk poodi jĂ”udis. Seega, arvestades kĂ”iki objekte vahepealseid liikumisi, ootame aastas kĂŒmneid miljardeid kirjeid.
Meeskond M
Ehkki 'Markus' on projektina osa H5-st, viiakse seda ellu toote lĂ€henemise abil. Meeskond töötab Scrum meetodil. Projekti algus oli eelmise aasta suvel, kuid esimesed tulemused ilmusid alles oktoobris â moodustati tĂ€ielikult omakĂ€eliselt meeskond, arendati vĂ€lja sĂŒsteemi arhitektuur ja osteti seadmed. Praegu on meeskonnas 16 inimest, kellest kuus tegelevad backend ja frontend arendamisega, kolm sĂŒsteemianalĂŒĂŒsi ning veel kuus tegelevad kĂ€sitsi, koormus- ja automatiseeritud testimise ning toote toetamisega. Lisaks on meie seas SRE-spetsialist.
Meie meeskonnas kirjutavad koodi mitte ainult arendajad, vaid praktiliselt kĂ”ik kolleegid oskavad programmeerida ja kirjutavad automatiseerimisteste, koormusskeeme ja automatiseerimise skripte. Me pöörame sellele erilist tĂ€helepanu, kuna isegi toote hooldus nĂ”uab kĂ”rget automatiseerimise taset. Kolleegidele, kes polnud varem programmeerinud, anname alati nĂ”u ja abi, andes neile vĂ€iksemaid ĂŒlesandeid.
Koroonaviiruse pandeemia tĂ”ttu viisime kogu meeskonna ĂŒle kaugtööle, kĂ”ik arenduse juhtimiseks vajalikud tööriistad, töötav töövoog Jira-s ja GitLab-is, vĂ”imaldasid selle etapi kergesti lĂ€bida. Kaugtööl veedetud kuukajad nĂ€itasid, et meeskonna tootlikkus ei langenud, paljudele tĂ”usis töö mugavus, ainus asi, mis puudu on, on elav suhtlemine.
Meeskonna koosolek enne kaugtööd

Koosolekud kaugtööl

Lahenduse tehnoloogia alus
H5 standardne hoidla ja CI/CD tööriist on GitLab. Kasutame seda koodi hoidmiseks, pidevaks testimiseks ja testimis- ja tootmiserveritesse paigutamiseks. Samuti praktiseerime koodi ĂŒlevaatust, kus vĂ€hemalt kaks kolleegi peavad arendaja koodimuudatused heaks kiitma. Statistilised koodi analĂŒsaatorid SonarQube ja JaCoCo aitavad meil koodi puhtana hoida ja tagada nĂ”utava taseme unit-testide katvust. KĂ”ik koodimuudatused peavad kindlasti lĂ€bi kĂ€ima nende kontrollide. KĂ”ik kĂ€sitsi kontrollitud teststsenaariumid automatiseeritakse hiljem.
Eduka Ă€riprotsessi tĂ€itmiseks 'Markus'iga pidime lahendama mitmeid tehnoloogilisi ĂŒlesandeid, millest rÀÀgime jĂ€rjestikku.
Ălesanne 1. SĂŒsteemi horisontaalse skaleeritavuse vajadus
Selle ĂŒlesande lahendamiseks valisime mikroteenuste arhitektuuri lĂ€henemise. Selle juures oli vĂ€ga tĂ€htis mĂ”ista teenuste vastutuse valdkondi. PĂŒĂŒdsime neid jagada Ă€ritehingute jĂ€rgi, arvestades protsesside spetsiifikat. NĂ€iteks inventuuri vastuvĂ”tt laos on haruldane, kuid mahukas operatsioon, mille kĂ€igus on oluline vĂ”imalikult kiiresti saada riiklikult reguleerivalt asutuselt teavet vastuvĂ”etavate kaupade ĂŒksuste kohta, kus ĂŒhe saatmise kogus vĂ”ib ulatuda kuni 600 000, kontrollida kauba vastuvĂ”tmise lubatavust laos ning edastada kogu vajalik teave laotehnika sĂŒsteemile. Kuid lao vĂ€ljastamine toimub palju suurema intensiivsuse juures, kuid sellega seondub vĂ€iksemate andmemahtude töötlemine.
KĂ”ik teenused rakendame stateless pĂ”himĂ”ttel ja pĂŒĂŒame isegi sisemisi operatsioone jagada sammudeks, kasutades meie enda nimel self-teemasid Kafka. See on olukord, kus mikroteenus saadab sĂ”numi endale, mis aitab tasakaalustada koormust ressursside nĂ”udlikumate operatsioonide puhul ja lihtsustab toote hooldust, kuid sellest rÀÀgime hiljem.
Otsustasime eraldada eraldi teenustesse moodulid, mis suhtlevad vĂ€listest sĂŒsteemidest. See vĂ”imaldas lahendada sageli muutuva vĂ€listesĂŒsteemide API probleemi, praktiliselt mĂ”jutamata Ă€rifunktsionaalsusega teenuseid.

KÔik mikroteenused paigaldatakse OpenShifti klastrisse, mis lahendab iga mikroteenuse skaleerimise probleemi ning vÔimaldab meil mitte kasutada kolmandate osapoolte teenuste avastamise tööriistu.
Ălesanne 2. Vajadus hoida kĂ”rget koormust ja vĂ€ga intensiivset andmevahetust platvormi teenuste vahel: ainult projekti kĂ€ivitamise faasis toimub umbes 600 operatsiooni sekundis. Ootame selle nĂ€itaja suurenemist kuni 5000 op/sec loomisel kaubandusobjektide meie platvormiga liitumise kĂ€igus.
Selle ĂŒlesande lahendamiseks rakendati Kafka klastrit ja peaaegu tĂ€ielikult loobuti platformi mikroteenuste vahelisest sĂŒnkroonsest suhtlemisest. See nĂ”uab sĂŒsteemi nĂ”uete vĂ€ga tĂ€helepanelikku analĂŒĂŒsi, kuna mitte kĂ”ik toimingud ei saa olla asĂŒnkroonsed. Samuti ei edasta me lihtsalt sĂŒndmusi vahendaja kaudu, vaid edastame sĂ”numis kogu vajaliku Ă€riteabe. SeetĂ”ttu vĂ”ib sĂ”numi suurus ulatuda sadadesse kilobaitidesse. Kafka sĂ”numite mahupiirang nĂ”uab meilt sĂ”numite suuruste tĂ€pset prognoosimist ja hĂ€daolukordade korral jagame neid, kuigi jagamine on loogiline ning seotud Ă€ritegevustega.
NĂ€iteks toote, mis on jĂ”udnud autoga, jagame kastidesse. SĂŒnkroonsete toimingute jaoks eraldatakse eraldi mikroteenused ja viiakse lĂ€bi pĂ”hjalik koormustestimine. Kafka kasutamine esitas meile uue vĂ€ljakutse â meie teenuse töö kontrollimine koos Kafka integreerimisega muudab kĂ”ik meie unit-testid asĂŒnkroonseteks. Selle ĂŒlesande lahendamiseks kirjutasime enda abimeetodid Using Embedded Kafka Broker. See ei ocean't tĂŒhista vajadust kirjutada unit-teste eraldi meetodite jaoks, kuid keerulisi juhtumeid eelistame testida Kafka kasutamisel.
Keskendume logide jĂ€lgimisele, et nende TraceId ei kaoks teenuste töös tekkivate erandite vĂ”i Kafka batch'i töötlemise kĂ€igus. Kui esimesega ei tekkinud erilisi probleeme, siis teise puhul peame logima kĂ”ik TraceId, millega batch saabus, ja valima ĂŒhe jĂ€tkamiseks jĂ€lgimisel. Nii suudab kasutaja algse TraceId jĂ€rgi otsides kergesti leida, millega jĂ€lgimine jĂ€tkus.
Ălesanne 3. Vajadus salvestada suures koguses andmeid: ĂŒle 1 miljardi mĂ€rgistuse aastas ainult tubaka kohta tuleb X5. Neid tuleb pidevalt ja kiiresti kĂ€tte saada. Kokku peab sĂŒsteem töötlema umbes 10 miljardit kirjet mĂ€rgistega toodete andmete ajaloos.
Kolmanda ĂŒlesande lahendamiseks valiti NoSQL andmebaas MongoDB. Meie sĂŒsteem on ĂŒles ehitatud 5 nodi shardist ja igas nodis on Replica Set 3 serveriga. See vĂ”imaldab sĂŒsteemi horisontaalselt skaleerida, lisades uusi servereid konstruktsiooni ja tagada selle talitlushĂ€ire kindel. Siin seisisime silmitsi teise probleemiga â tehingute tagamise tagamise Mongo klastris, arvestades horisontaalselt skaleeritavate mikroteenuste kasutamist. NĂ€iteks on ĂŒheks meie sĂŒsteemi ĂŒlesandeks tuvastada kauba korduvmĂŒĂŒmise katseid sama mĂ€rkekoodiga. Siit tekivad probleemid vale skaneerimise vĂ”i vale kassaprotseduuri tĂ”ttu. Oleme avastanud, et sellised dubleerimised vĂ”ivad tekkida nii ĂŒhe töötleva Kafka partii sees kui ka kahe paralleelselt töödeldava partii vahel. Seega ei andnud duplikaatide kontrollimine andmebaasi pĂ€ringu kaudu mitte midagi. Iga mikroteenuse puhul lahendasime probleemi eraldi, lĂ€htudes selle teenuse Ă€ri loogikast. NĂ€iteks, tĆĄekkide puhul lisasime kontrolli partii sees ja eraldi töötlemise duplikaatide ilmnemiseks sisestamisel.
Et kasutajate tegevus operatsioonide ajaloos ei mĂ”jutaks meie Ă€ri protsesside pĂ”hilist toimimist, eraldasime kĂ”ik ajaloolised andmed eraldi teenuseks koos eraldi andmebaasiga, mis samuti saab teavet ĂŒle Kafka. Nii saavad kasutajad töötada eraldi teenusega, ilma et see mĂ”jutaks teenuseid, mis töötlevad andmeid praeguste operatsioonide kohta.
Ălesanne 4. JĂ€rjestuste uuesti töötlemine ja jĂ€lgimine:
Jaotatud sĂŒsteemides tekivad vĂ€ltimatult probleemid ja vigade esitamisega andmebaaside, jĂ€rjekordade ja vĂ€liste andmeallikate kĂ€ttesaadavuses. 'Markuse' puhul on selliste vigade allikaks integreerimine vĂ€liste sĂŒsteemidega. Oli vajalik leida lahendus, mis vĂ”imaldab vigu koguda ja saata re-definitsiooniga veinimajadele mĂ”ningase mÀÀratud ajaga, kuid ei takista edukaid pĂ€ringute töötlemist peamises jĂ€rjekorras. Selleks valiti nn kontseptsioon "teema pĂ”hineb uuesti proovima". Iga pĂ”hiteema jaoks luuakse ĂŒks vĂ”i mitu retry teemat, kuhu suunatakse vigased sĂ”numid ja seelĂ€bi vĂ€listatakse viivitus peamise teema sĂ”numite töötlemisel. Koostoime skeem -

Selle skeemi rakendamiseks vajasime jĂ€rgmist - integreerida see lahendus Springiga ja vĂ€ltida koodi dubleerimist. Internetis sattusime sarnasele lahendusele, mis pĂ”hines Spring BeanPostProcessoril, kuid see tundus meile ĂŒlemÀÀra kohmakas. Meie meeskond leidis lihtsama lahenduse, mis vĂ”imaldab integreeruda Springi consumerite loomise tsĂŒklisse ja lisada tĂ€iendavalt Retry consumer'eid. Meie lahenduse prototĂŒĂŒbi pakkusime Springi meeskonnale, seda saab vaadata . Retry consumer'ite arv ja iga consumer'i katsete arv seadistatakse parameetrite kaudu vastavalt Ă€riprotsessi vajadustele, ning et kĂ”ik töötaks, tuleb lihtsalt paigaldada kĂ”igile Springi arendajatele tuttav annotatsioon org.springframework.kafka.annotation.KafkaListener.
Kui sĂ”numit ei Ă”nnestunud kĂ”ikide retry katsete jĂ€rel töödelda, jĂ”uab see DLT-le (dead letter topic) Spring DeadLetterPublishingRecoverer'i abil. Tugiteenuse soovil laiendasime seda funktsionaalsust ja lĂ”ime eraldi teenuse, mis vĂ”imaldab vaadata DLT-sse sattunud sĂ”numeid, stackTrace'i, traceId-d ja muud kasulikku teavet. Lisaks lisatud monitooringud ja hĂ€iresĂŒsteemid kĂ”igile DLT teemadele, ning nĂŒĂŒd on DLT teema sĂ”numi ilmumine pĂ”hjus probleemi analĂŒĂŒsimiseks ja defekti avamiseks. See on vĂ€ga mugav - teema nime jĂ€rgi mĂ”istame kohe, millises protsessi etapis probleem tekkis, mis kiirendab oluliselt juurepĂ”hjuse otsimist.

Hiljuti rakendasime liidese, mis vĂ”imaldab meie toetuse kaudu sĂ”numeid uuesti saata pĂ€rast nende pĂ”hjuste kĂ”rvaldamist (nĂ€iteks, vĂ€lise sĂŒsteemi töövĂ”ime taastamine) ja muidugi avada vastav defekt analĂŒĂŒsiks. Siin tulid kasuks meie self-teemad, et mitte taaskĂ€ivitada pikka töötlemisahelat, saab seda taaskĂ€ivitada vajalikust sammust.

Platvormi ekspluateerimine
Platvorm on juba tootmiseksponeeritud, iga pĂ€ev teeme tarnet ja laadimist, ĂŒhendame uusi jaotuskeskusi ja poode. Pilootprojektina töötab sĂŒsteem kaubagruppidega "Tubakas" ja "Jalatsid".
Kogu meie meeskond osaleb pilootide lĂ€biviimisel, analĂŒĂŒsib tekkinud probleeme ja teeb ettepanekuid meie toote tĂ€iustamiseks, alates logide tĂ€iustamisest kuni protsesside muutmiseni.
Kuna vÀltida oma vigade kordamist, kajastuvad kÔik pilootprojekti kÀigus leitud juhtumid automatiseeritud testides. Suure arvu automatiseeritud ja unit-testide olemasolu vÔimaldab lÀbi viia regressiooniteste ja rakendada hotfixe sisuliselt paari tunni jooksul.
Praegu jÀtkame oma platvormi arendamist ja tÀiustamist ning seisame pidevalt silmitsi uute vÀljakutsetega. Kui olete huvitatud, rÀÀgime meie lahendustest jÀrgmistes artiklites.
Allikas: habr.com
