“Hodam u mojim cipelama” - čekaj, jesu li označene?

Od 2019. Rusija ima zakon o obveznom označavanju. Zakon se ne odnosi na sve skupine robe, a datumi stupanja na snagu obveznog označavanja za skupine proizvoda su različiti. Duhan, obuća i lijekovi prvi će biti pod obveznim označavanjem, a kasnije će se dodati i ostali proizvodi, primjerice parfemi, tekstil i mlijeko. Ova zakonska novina potaknula je razvoj novih informatičkih rješenja koja će omogućiti praćenje cijelog životnog lanca proizvoda od proizvodnje do kupnje od strane krajnjeg potrošača, do svih sudionika u procesu: i same države i svih organizacija koje prodaju robu s obvezno označavanje.

U X5, sustav koji će pratiti označenu robu i razmjenjivati ​​podatke s vladom i dobavljačima zove se “Marcus”. Recimo vam redom kako i tko ga je razvio, koji je njegov tehnološki sklop i zašto imamo čime biti ponosni.

“Hodam u mojim cipelama” - čekaj, jesu li označene?

Pravi HighLoad

“Marcus” rješava mnoge probleme, a glavni je integracijska interakcija između X5 informacijskih sustava i državnog informacijskog sustava za označene proizvode (GIS MP) za praćenje kretanja označenih proizvoda. Platforma također pohranjuje sve kodove za označavanje koje smo primili i cijelu povijest kretanja tih kodova po objektima te pomaže u eliminaciji ponovnog ocjenjivanja označenih proizvoda. Na primjeru duhanskih proizvoda, koji su bili uvršteni u prve skupine označene robe, samo jedan šleper cigareta sadrži oko 600 paklica od kojih svaka ima svoju jedinstvenu šifru. A zadatak našeg sustava je pratiti i provjeravati zakonitost kretanja svakog takvog pakiranja između skladišta i trgovina, te u konačnici provjeriti dopuštenost njihove prodaje krajnjem kupcu. A mi bilježimo oko 000 gotovinskih transakcija po satu, a trebamo evidentirati i kako je koja takva kutija ušla u trgovinu. Dakle, uzimajući u obzir sva kretanja između objekata, očekujemo desetke milijardi zapisa godišnje.

Tim M

Unatoč činjenici da se Marcus smatra projektom unutar X5, on se implementira koristeći proizvodni pristup. Tim radi po Scrumu. Projekt je krenuo prošlog ljeta, ali prvi rezultati stigli su tek u listopadu - vlastiti tim je u potpunosti okupiran, razvijena je arhitektura sustava i nabavljena je oprema. Sada tim ima 16 ljudi, od kojih je šest uključeno u backend i frontend razvoj, od kojih je troje uključeno u analizu sustava. Još šest ljudi uključeno je u ručno, opterećenje, automatizirano testiranje i održavanje proizvoda. Osim toga, imamo SRE stručnjaka.

Ne samo programeri pišu kod u našem timu; gotovo svi dečki znaju kako programirati i pisati autotestove, učitavati skripte i skripte za automatizaciju. Tome pridajemo posebnu pozornost jer čak i podrška proizvoda zahtijeva visoku razinu automatizacije. Uvijek nastojimo savjetovati i pomoći kolegama koji do sada nisu programirali te im dati neke male zadatke da rade.

Zbog pandemije koronavirusa cijeli tim prebacili smo na daljinski rad, dostupnost svih alata za upravljanje razvojem, izgrađen tijek rada u Jiri i GitLabu omogućili su da se lako prođe ova faza. Mjeseci provedeni na daljinu pokazali su da time nije patila produktivnost tima, mnogima se povećala udobnost na poslu, a nedostajala je samo živa komunikacija.

Timski sastanak na daljinu

“Hodam u mojim cipelama” - čekaj, jesu li označene?

Sastanci tijekom rada na daljinu

“Hodam u mojim cipelama” - čekaj, jesu li označene?

Tehnološki skup rješenja

Standardni repozitorij i CI/CD alat za X5 je GitLab. Koristimo ga za pohranu koda, kontinuirano testiranje i implementaciju na testne i proizvodne poslužitelje. Također koristimo praksu pregleda koda, kada najmanje 2 kolege trebaju odobriti promjene koje je programer napravio u kodu. Statički analizatori koda SonarQube i JaCoCo pomažu nam da naš kod bude čist i osiguravaju potrebnu razinu pokrivenosti jediničnim testom. Sve promjene koda moraju proći ove provjere. Sve testne skripte koje se pokreću ručno naknadno se automatiziraju.

Za uspješnu implementaciju poslovnih procesa tvrtke “Marcus” morali smo riješiti niz tehnoloških problema, o svakom redom.

Zadatak 1. Potreba za horizontalnom skalabilnošću sustava

Kako bismo riješili ovaj problem, odabrali smo mikroservisni pristup arhitekturi. Pritom je bilo vrlo važno razumjeti područja odgovornosti službi. Nastojali smo ih podijeliti na poslovne operacije, vodeći računa o specifičnostima procesa. Na primjer, prihvaćanje u skladištu nije vrlo česta, ali vrlo velika operacija, tijekom koje je potrebno brzo dobiti od državnog regulatora podatke o jedinicama robe koje se prihvaćaju, čiji broj u jednoj isporuci doseže 600000 , provjerite dopuštenost preuzimanja ovog proizvoda u skladište i vratite sve potrebne podatke za sustav automatizacije skladišta. Ali otprema iz skladišta ima puno veći intenzitet, ali istovremeno radi s malim količinama podataka.

Implementiramo sve usluge bez statusa i čak pokušavamo podijeliti interne operacije u korake, koristeći ono što nazivamo Kafkinim temama o sebi. Tada mikroservis šalje poruku samom sebi, što vam omogućuje da uravnotežite opterećenje na operacijama koje zahtijevaju više resursa i pojednostavljuje održavanje proizvoda, ali o tome kasnije.

Odlučili smo odvojiti module za interakciju s vanjskim sustavima u zasebne usluge. Time je omogućeno rješavanje problema čestog mijenjanja API-ja vanjskih sustava, praktički bez utjecaja na servise s poslovnom funkcionalnošću.

“Hodam u mojim cipelama” - čekaj, jesu li označene?

Sve mikrousluge raspoređene su u klasteru OpenShift, što rješava i problem skaliranja svake mikrousluge i omogućuje nam da ne koristimo alate treće strane za otkrivanje usluga.

Zadatak 2. Potreba za održavanjem visokog opterećenja i vrlo intenzivne razmjene podataka između usluga platforme: Samo u fazi pokretanja projekta izvodi se oko 600 operacija u sekundi. Očekujemo da će se ova vrijednost povećati na 5000 ops/sec kako se prodajna mjesta povezuju s našom platformom.

Ovaj problem je riješen implementacijom Kafka klastera i gotovo potpunim napuštanjem sinkrone interakcije između mikroservisa platforme. Ovo zahtijeva vrlo pažljivu analizu zahtjeva sustava, jer ne mogu sve operacije biti asinkrone. Istodobno, ne samo da prenosimo događaje preko brokera, već također prenosimo sve potrebne poslovne informacije u poruci. Dakle, veličina poruke može doseći nekoliko stotina kilobajta. Ograničenje veličine poruka u Kafki zahtijeva da točno predvidimo veličinu poruka, te ih po potrebi podijelimo, no podjela je logična, vezana uz poslovanje.
Primjerice, robu koja stigne u automobilu dijelimo u kutije. Za sinkrone operacije dodjeljuju se zasebni mikroservisi i provodi se temeljito testiranje opterećenja. Korištenje Kafke dovelo nas je pred još jedan izazov - testiranje rada naše usluge uzimajući u obzir Kafka integraciju čini sve naše jedinične testove asinkronima. Riješili smo ovaj problem pisanjem vlastitih pomoćnih metoda pomoću Embedded Kafka Brokera. Ovo ne eliminira potrebu za pisanjem jediničnih testova za pojedinačne metode, ali radije testiramo složene slučajeve koristeći Kafku.

Puno je pažnje posvećeno praćenju logova kako se njihov TraceId ne bi izgubio kada dođe do iznimaka tijekom rada servisa ili rada s Kafka batchom. A ako nije bilo posebnih problema s prvim, tada smo u drugom slučaju prisiljeni zabilježiti sve TraceId-ove s kojima je paket došao i odabrati jedan za nastavak praćenja. Tada će korisnik pri pretraživanju po izvornom TraceId-u vrlo lako saznati s kojim je praćenjem nastavljeno.

Zadatak 3. Potreba za pohranjivanjem velike količine podataka: Više od 1 milijarde etiketa godišnje samo za duhan dolazi u X5. Oni zahtijevaju stalan i brz pristup. Ukupno, sustav mora obraditi oko 10 milijardi zapisa o povijesti kretanja te označene robe.

Za rješavanje trećeg problema odabrana je NoSQL baza podataka MongoDB. Izgradili smo dio od 5 čvorova i svaki čvor ima skup replika od 3 poslužitelja. To vam omogućuje vodoravno skaliranje sustava, dodavanjem novih poslužitelja u klaster i osiguravanje njegove tolerancije na pogreške. Ovdje smo se susreli s još jednim problemom - osiguranjem transakcijske sposobnosti u mongo klasteru, uzimajući u obzir korištenje horizontalno skalabilnih mikroservisa. Na primjer, jedan od zadataka našeg sustava je identificirati pokušaje preprodaje proizvoda s istim šiframa označavanja. Ovdje se pojavljuju slojevi s pogrešnim skeniranjem ili pogrešnim operacijama blagajnika. Otkrili smo da se takvi duplikati mogu pojaviti i unutar jedne Kafka serije koja se obrađuje, i unutar dvije serije koje se obrađuju paralelno. Stoga provjera duplikata upitom u bazu podataka nije dala ništa. Za svaku smo mikroservisu problem rješavali zasebno na temelju poslovne logike te usluge. Na primjer, za provjere smo dodali provjeru unutar serije i zasebnu obradu za pojavu duplikata prilikom umetanja.

Kako rad korisnika s poviješću poslovanja ni na koji način ne bi utjecao na ono najvažnije - funkcioniranje naših poslovnih procesa, sve smo povijesne podatke izdvojili u zasebnu uslugu sa zasebnom bazom podataka, koja također dobiva informacije preko Kafke . Na ovaj način korisnici rade s izoliranom uslugom bez utjecaja na usluge koje obrađuju podatke za tekuće operacije.

Zadatak 4: Ponovna obrada reda čekanja i nadzor:

U distribuiranim sustavima neizbježno se javljaju problemi i pogreške u dostupnosti baza podataka, redova čekanja i vanjskih izvora podataka. U slučaju Marcusa, izvor takvih grešaka je integracija s vanjskim sustavima. Bilo je potrebno pronaći rješenje koje bi omogućilo ponovljene zahtjeve za pogrešne odgovore s određenim timeoutom, ali istovremeno ne bi zaustavilo obradu uspješnih zahtjeva u glavnom redu čekanja. U tu svrhu odabran je takozvani koncept "ponovnog pokušaja temeljen na temi". Za svaku glavnu temu kreira se jedna ili više tema za ponovni pokušaj na koje se šalju pogrešne poruke i ujedno se eliminira kašnjenje u obradi poruka iz glavne teme. Shema interakcije -

“Hodam u mojim cipelama” - čekaj, jesu li označene?

Za implementaciju takve sheme bilo nam je potrebno sljedeće: integrirati ovo rješenje sa Springom i izbjeći dupliciranje koda. Dok smo surfali internetom, naišli smo na slično rješenje temeljeno na Spring BeanPostProccessoru, ali nam se činilo nepotrebno glomaznim. Naš tim je napravio jednostavnije rješenje koje nam omogućuje integraciju u Spring ciklus za kreiranje potrošača i dodatno dodavanje Retry Consumers. Ponudili smo prototip našeg rješenja Spring timu, možete ga vidjeti ovdje. Broj Retry Consumers i broj pokušaja za svakog potrošača se konfigurira kroz parametre, ovisno o potrebama poslovnog procesa, a da bi sve funkcioniralo, preostaje samo dodati annotation org.springframework.kafka.annotation.KafkaListener , koji je poznat svim programerima Springa.

Ako se poruka ne može obraditi nakon svih ponovnih pokušaja, odlazi u DLT (tema mrtvog pisma) pomoću Spring DeadLetterPublishingRecoverer. Na zahtjev podrške, proširili smo ovu funkcionalnost i stvorili zasebnu uslugu koja vam omogućuje pregled poruka uključenih u DLT, stackTrace, traceId i druge korisne informacije o njima. Osim toga, nadzor i upozorenja dodani su svim temama DLT-a, a sada je zapravo pojavljivanje poruke u temi DLT razlog za analizu i popravak kvara. Ovo je vrlo zgodno - po nazivu teme odmah razumijemo na kojem je koraku procesa problem nastao, što značajno ubrzava potragu za njegovim temeljnim uzrokom.

“Hodam u mojim cipelama” - čekaj, jesu li označene?

Nedavno smo implementirali sučelje koje nam omogućuje ponovno slanje poruka koristeći našu podršku nakon uklanjanja njihovih uzroka (na primjer, ponovno uspostavljanje funkcionalnosti vanjskog sustava) i, naravno, utvrđivanje odgovarajućeg kvara za analizu. Ovdje dobro dolaze naše teme o sebi: kako ne biste ponovno pokrenuli dugi lanac obrade, možete ga ponovno pokrenuti od željenog koraka.

“Hodam u mojim cipelama” - čekaj, jesu li označene?

Rad platforme

Platforma je već u produktivnom radu, svaki dan vršimo isporuke i otpreme, povezujemo nove distribucijske centre i trgovine. U sklopu pilota, sustav radi s grupama proizvoda “Duhan” i “Obuća”.

Cijeli naš tim sudjeluje u provođenju pilota, analizira novonastale probleme i daje prijedloge za poboljšanje našeg proizvoda, od poboljšanja dnevnika do promjene procesa.

Kako ne bismo ponavljali naše pogreške, svi slučajevi pronađeni tijekom pilota odražavaju se u automatiziranim testovima. Prisutnost velikog broja autotestova i jediničnih testova omogućuje vam provođenje regresijskog testiranja i instaliranje hitnog popravka doslovno u roku od nekoliko sati.

Sada nastavljamo razvijati i poboljšavati našu platformu, te se neprestano suočavamo s novim izazovima. Ako ste zainteresirani, govorit ćemo o našim rješenjima u sljedećim člancima.

Izvor: www.habr.com

Dodajte komentar