"Gå i mine sko" - vent, er de mærket?

Siden 2019 har Rusland haft en lov om obligatorisk mærkning. Loven gælder ikke for alle varegrupper, og datoerne for ikrafttræden af ​​obligatorisk mærkning for produktgrupper er forskellige. Tobak, sko og medicin vil være de første, der skal være underlagt obligatorisk mærkning; andre produkter vil blive tilføjet senere, for eksempel parfume, tekstiler og mælk. Denne lovgivningsmæssige innovation foranledigede udviklingen af ​​nye it-løsninger, der vil gøre det muligt at spore hele livskæden for et produkt fra produktion til køb af slutforbrugeren til alle deltagere i processen: både staten selv og alle organisationer, der sælger varer med obligatorisk mærkning.

I X5 kaldes systemet, der vil spore mærkede varer og udveksle data med staten og leverandører, "Marcus". Lad os fortælle dig i rækkefølge, hvordan og hvem der har udviklet det, hvad dets teknologistack er, og hvorfor vi har noget at være stolte af.

"Gå i mine sko" - vent, er de mærket?

Rigtig højbelastning

"Marcus" løser mange problemer, det vigtigste er integrationsinteraktionen mellem X5 informationssystemer og det statslige informationssystem for mærkede produkter (GIS MP) for at spore bevægelsen af ​​mærkede produkter. Platformen gemmer også alle mærkningskoder modtaget af os og hele historien om bevægelsen af ​​disse koder på tværs af objekter, og hjælper med at eliminere omklassificering af mærkede produkter. Ved at bruge eksemplet med tobaksvarer, som var inkluderet i de første grupper af mærkede varer, indeholder kun en lastbil cigaretter omkring 600 pakker, som hver har sin egen unikke kode. Og opgaven med vores system er at spore og verificere lovligheden af ​​bevægelserne af hver sådan pakke mellem lagre og butikker og i sidste ende verificere, om deres salg er tilladt til slutkøberen. Og vi registrerer omkring 000 kontanttransaktioner i timen, og vi skal også registrere, hvordan hver sådan pakke kom ind i butikken. Når vi tager alle bevægelser mellem objekter i betragtning, forventer vi således titusindvis af milliarder af optegnelser om året.

Hold M

På trods af at Marcus betragtes som et projekt inden for X5, bliver det implementeret ved hjælp af en produkttilgang. Teamet arbejder efter Scrum. Projektet startede sidste sommer, men de første resultater kom først i oktober – vores eget team var færdigmonteret, systemarkitekturen blev udviklet og udstyr blev indkøbt. Nu har teamet 16 personer, hvoraf seks er involveret i backend- og frontend-udvikling, hvoraf tre er involveret i systemanalyse. Yderligere seks personer er involveret i manuel, belastning, automatiseret test og produktvedligeholdelse. Derudover har vi en SRE-specialist.

Ikke kun udviklere skriver kode i vores team; næsten alle fyrene ved, hvordan man programmerer og skriver autotests, indlæser scripts og automatiseringsscripts. Vi er særligt opmærksomme på dette, da selv produktsupport kræver en høj grad af automatisering. Vi forsøger altid at rådgive og hjælpe kolleger, der ikke har programmeret før, og giver dem nogle små opgaver at arbejde med.

På grund af coronavirus-pandemien overførte vi hele teamet til fjernarbejde; tilgængeligheden af ​​alle værktøjer til udviklingsstyring, den indbyggede arbejdsgang i Jira og GitLab gjorde det muligt nemt at passere denne fase. De måneder, der blev brugt på afstand, viste, at holdets produktivitet ikke led som et resultat; for mange steg komforten på arbejdet, det eneste, der manglede, var livekommunikation.

Fjernholdsmøde

"Gå i mine sko" - vent, er de mærket?

Møder under fjernarbejde

"Gå i mine sko" - vent, er de mærket?

Teknologistabel af løsningen

Standardlageret og CI/CD-værktøjet til X5 er GitLab. Vi bruger det til kodelagring, kontinuerlig test og udrulning til test- og produktionsservere. Vi bruger også praksis med kodegennemgang, når mindst 2 kolleger skal godkende ændringer foretaget af udvikleren til koden. Statiske kodeanalysatorer SonarQube og JaCoCo hjælper os med at holde vores kode ren og sikre det nødvendige niveau af enhedstestdækning. Alle ændringer af koden skal gennemgå disse kontroller. Alle testscripts, der køres manuelt, bliver efterfølgende automatiseret.

For at "Marcus" kunne implementere forretningsprocesser med succes, var vi nødt til at løse en række teknologiske problemer, om hver i rækkefølge.

Opgave 1. Behovet for horisontal skalerbarhed af systemet

For at løse dette problem valgte vi en mikroservicetilgang til arkitektur. Samtidig var det meget vigtigt at forstå ydelsernes ansvarsområder. Vi forsøgte at opdele dem i forretningsdrift under hensyntagen til processernes detaljer. For eksempel er accept på et lager ikke en meget hyppig, men meget storstilet operation, hvor det er nødvendigt hurtigt at indhente oplysninger fra statsregulatoren om de enheder af varer, der accepteres, hvis antal i en levering når 600000 , kontroller, om det er tilladt at acceptere dette produkt på lageret, og returner alle nødvendige oplysninger til lagerautomatiseringssystemet. Men forsendelse fra lagre har en meget større intensitet, men opererer samtidig med små mængder data.

Vi implementerer alle tjenester på et statsløst grundlag og forsøger endda at opdele interne operationer i trin ved at bruge det, vi kalder Kafka selv-emner. Det er, når en mikroservice sender en besked til sig selv, som giver dig mulighed for at balancere belastningen på mere ressourcekrævende operationer og forenkler produktvedligeholdelsen, men mere om det senere.

Vi besluttede at opdele moduler til interaktion med eksterne systemer i separate tjenester. Dette gjorde det muligt at løse problemet med hyppigt skiftende API'er af eksterne systemer, stort set uden indflydelse på tjenester med forretningsfunktionalitet.

"Gå i mine sko" - vent, er de mærket?

Alle mikrotjenester er implementeret i en OpenShift-klynge, som både løser problemet med at skalere hver mikrotjeneste og giver os mulighed for ikke at bruge tredjeparts Service Discovery-værktøjer.

Opgave 2. Behovet for at opretholde en høj belastning og meget intensiv dataudveksling mellem platformstjenester: Alene under projektstartfasen udføres omkring 600 operationer i sekundet. Vi forventer, at denne værdi vil stige til 5000 ops/sek., efterhånden som detailforretninger opretter forbindelse til vores platform.

Dette problem blev løst ved at implementere en Kafka-klynge og næsten helt opgive synkron interaktion mellem platformens mikrotjenester. Dette kræver en meget omhyggelig analyse af systemkravene, da ikke alle operationer kan være asynkrone. Samtidig transmitterer vi ikke kun begivenheder gennem mægleren, men transmitterer også alle de nødvendige forretningsoplysninger i beskeden. Således kan meddelelsesstørrelsen nå op på flere hundrede kilobyte. Beskedstørrelsesgrænsen i Kafka kræver, at vi præcist forudsiger meddelelsesstørrelsen, og om nødvendigt opdeler vi dem, men opdelingen er logisk, relateret til forretningsdrift.
For eksempel deler vi varer, der ankommer i en bil, i kasser. Til synkrone operationer tildeles separate mikrotjenester, og der udføres grundig belastningstest. Brugen af ​​Kafka gav os en anden udfordring - at teste driften af ​​vores tjeneste under hensyntagen til Kafka-integrationen gør alle vores enhedstests asynkrone. Vi løste dette problem ved at skrive vores egne hjælpemetoder ved hjælp af Embedded Kafka Broker. Dette eliminerer ikke behovet for at skrive enhedstests for individuelle metoder, men vi foretrækker at teste komplekse cases ved hjælp af Kafka.

Der blev lagt megen vægt på at spore logfiler, så deres TraceId ikke ville gå tabt, når der opstår undtagelser under driften af ​​tjenester eller ved arbejde med Kafka batch. Og hvis der ikke var særlige problemer med den første, så er vi i det andet tilfælde tvunget til at logge alle de TraceId'er, som partiet kom med, og vælge en for at fortsætte sporingen. Når brugeren derefter søger med det originale TraceId, vil brugeren nemt finde ud af, med hvilken sporingen fortsatte.

Opgave 3. Behovet for at gemme en stor mængde data: Mere end 1 milliard mærker om året for tobak alene kommer til X5. De kræver konstant og hurtig adgang. I alt skal systemet behandle omkring 10 milliarder registreringer af bevægelseshistorien for disse mærkede varer.

For at løse det tredje problem blev NoSQL-databasen MongoDB valgt. Vi har bygget et skår af 5 noder, og hver node har et replikasæt med 3 servere. Dette giver dig mulighed for at skalere systemet vandret, tilføje nye servere til klyngen og sikre dets fejltolerance. Her stødte vi på et andet problem - at sikre transaktionalitet i mongo-klyngen under hensyntagen til brugen af ​​horisontalt skalerbare mikrotjenester. For eksempel er en af ​​opgaverne i vores system at identificere forsøg på at videresælge produkter med de samme mærkningskoder. Her optræder overlays med fejlscanninger eller fejlbetjeninger af kasserere. Vi fandt ud af, at sådanne dubletter kan forekomme både inden for én Kafka-batch, der behandles, og inden for to batches, der behandles parallelt. Det gav således ikke noget at tjekke for dubletter ved at forespørge i databasen. For hver mikroservice løste vi problemet separat baseret på denne services forretningslogik. For eksempel, til kontrol, tilføjede vi en check inde i batch og separat behandling for udseendet af dubletter ved indsættelse.

For at sikre, at brugernes arbejde med driftshistorikken ikke på nogen måde påvirker det vigtigste - funktionen af ​​vores forretningsprocesser, har vi adskilt alle historiske data i en separat tjeneste med en separat database, som også modtager information gennem Kafka . På denne måde arbejder brugere med en isoleret tjeneste uden at påvirke de tjenester, der behandler data til løbende drift.

Opgave 4: Genbehandling og overvågning af kø:

I distribuerede systemer opstår der uundgåeligt problemer og fejl i tilgængeligheden af ​​databaser, køer og eksterne datakilder. I Marcus' tilfælde er kilden til sådanne fejl integration med eksterne systemer. Det var nødvendigt at finde en løsning, der ville tillade gentagne anmodninger om fejlagtige svar med en vis specificeret timeout, men samtidig ikke stoppe med at behandle vellykkede anmodninger i hovedkøen. Til dette formål blev det såkaldte "topic based retry"-koncept valgt. For hvert hovedemne oprettes et eller flere genforsøgsemner, hvortil der sendes fejlbeskeder og samtidig elimineres forsinkelsen i behandlingen af ​​beskeder fra hovedemnet. Interaktionsskema -

"Gå i mine sko" - vent, er de mærket?

For at implementere en sådan ordning havde vi brug for følgende: at integrere denne løsning med Spring og undgå kodeduplikering. Mens vi surfede på nettet, stødte vi på en lignende løsning baseret på Spring BeanPostProccessor, men den virkede unødvendigt besværlig for os. Vores team har lavet en enklere løsning, der giver os mulighed for at integrere i forårets cyklus for at skabe forbrugere og derudover tilføje Retry Consumers. Vi tilbød en prototype af vores løsning til Spring-teamet, du kan se den her. Antallet af Forsøg-forbrugere og antallet af forsøg for hver forbruger konfigureres gennem parametre, afhængigt af forretningsprocessens behov, og for at alt fungerer, er der kun tilbage at tilføje annotationen org.springframework.kafka.annotation.KafkaListener , som er kendt for alle Spring-udviklere.

Hvis meddelelsen ikke kunne behandles efter alle genforsøg, går den til DLT (dead letter topic) ved hjælp af Spring DeadLetterPublishingRecoverer. Efter anmodning fra support udvidede vi denne funktionalitet og skabte en separat tjeneste, der giver dig mulighed for at se meddelelser inkluderet i DLT, stackTrace, traceId og andre nyttige oplysninger om dem. Derudover blev der tilføjet overvågning og advarsler til alle DLT-emner, og nu er forekomsten af ​​en besked i et DLT-emne faktisk en grund til at analysere og rette en defekt. Dette er meget praktisk - ved emnets navn forstår vi straks, på hvilket trin i processen problemet opstod, hvilket markant fremskynder søgningen efter dens grundlæggende årsag.

"Gå i mine sko" - vent, er de mærket?

Senest har vi implementeret en grænseflade, der giver os mulighed for at sende meddelelser igen ved hjælp af vores support efter at have elimineret deres årsager (for eksempel gendannelse af funktionaliteten af ​​det eksterne system) og selvfølgelig etablere den tilsvarende defekt til analyse. Det er her, vores selvemner er nyttige: For ikke at genstarte en lang behandlingskæde, kan du genstarte den fra det ønskede trin.

"Gå i mine sko" - vent, er de mærket?

Betjening af platform

Platformen er allerede i produktiv drift, hver dag udfører vi leverancer og forsendelser, forbinder nye distributionscentre og butikker. Som en del af pilotprojektet arbejder systemet med produktgrupperne "Tobak" og "Sko".

Hele vores team deltager i at udføre pilotprojekter, analyserer nye problemer og kommer med forslag til forbedring af vores produkt, fra forbedring af logfiler til ændring af processer.

For ikke at gentage vores fejl, afspejles alle tilfælde fundet under piloten i automatiserede tests. Tilstedeværelsen af ​​et stort antal autotest og enhedstest giver dig mulighed for at udføre regressionstest og installere et hotfix bogstaveligt talt inden for et par timer.

Nu fortsætter vi med at udvikle og forbedre vores platform og står konstant over for nye udfordringer. Hvis du er interesseret, vil vi tale om vores løsninger i de følgende artikler.

Kilde: www.habr.com

Tilføj en kommentar