Siden 2019 har Russland hatt en lov om obligatorisk merking. Loven gjelder ikke for alle varegrupper, og datoene for ikrafttredelse av obligatorisk merking for produktgrupper er forskjellige. Tobakk, sko og medisiner vil vÊre de fÞrste som skal merkes obligatorisk, andre produkter vil bli lagt til senere, for eksempel parfyme, tekstiler og melk. Denne lovgivningsinnovasjonen fÞrte til utviklingen av nye IT-lÞsninger som vil gjÞre det mulig Ä spore hele livskjeden til et produkt fra produksjon til kjÞp av sluttforbrukeren, til alle deltakere i prosessen: bÄde staten selv og alle organisasjoner som selger varer med obligatorisk merking.
I X5 heter systemet som skal spore merkede varer og utveksle data med staten og leverandĂžrer "Marcus". La oss fortelle deg i rekkefĂžlge hvordan og hvem som utviklet den, hva teknologistabelen er, og hvorfor vi har noe Ă„ vĂŠre stolte av.

Ekte hĂžybelastning
"Marcus" lÞser mange problemer, det viktigste er integrasjonssamspillet mellom X5 informasjonssystemer og det statlige informasjonssystemet for merkede produkter (GIS MP) for Ä spore bevegelsen til merkede produkter. Plattformen lagrer ogsÄ alle merkekoder mottatt av oss og hele historien om bevegelsen av disse kodene pÄ tvers av objekter, og bidrar til Ä eliminere omgradering av merkede produkter. Ved Ä bruke eksemplet med tobakksprodukter, som var inkludert i de fÞrste gruppene av merkede varer, inneholder bare én lastebil med sigaretter omtrent 600 000 pakker, som hver har sin egen unike kode. Og oppgaven til systemet vÄrt er Ä spore og verifisere lovligheten av bevegelsene til hver slik pakke mellom varehus og butikker, og til slutt sjekke om salget er tillatt til sluttkjÞperen. Og vi registrerer omtrent 125 000 kontanttransaksjoner i timen, og vi mÄ ogsÄ registrere hvordan hver slik pakke kom inn i butikken. NÄr vi tar i betraktning alle bevegelsene mellom objekter, forventer vi altsÄ titalls milliarder poster per Är.
Team M
Til tross for at Marcus regnes som et prosjekt innenfor X5, blir det implementert ved hjelp av en produkttilnĂŠrming. Teamet jobber etter Scrum. Prosjektet startet i fjor sommer, men de fĂžrste resultatene kom fĂžrst i oktober â vĂ„rt eget team var ferdig montert, systemarkitekturen ble utviklet og utstyr ble kjĂžpt inn. NĂ„ har teamet 16 personer, hvorav seks er involvert i backend- og frontend-utvikling, hvorav tre er involvert i systemanalyse. Seks flere personer er involvert i manuell, last, automatisert testing og produktvedlikehold. I tillegg har vi en SRE-spesialist.
Ikke bare utviklere skriver kode i teamet vÄrt; nesten alle gutta vet hvordan de skal programmere og skrive autotester, laste skript og automatiseringsskript. Vi er spesielt oppmerksomme pÄ dette, siden selv produktstÞtte krever en hÞy grad av automatisering. Vi prÞver alltid Ä gi rÄd og hjelpe kolleger som ikke har programmert fÞr, og gi dem noen smÄ oppgaver Ä jobbe med.
PÄ grunn av koronaviruspandemien overfÞrte vi hele teamet til fjernarbeid; tilgjengeligheten av alle verktÞy for utviklingsstyring, den innebygde arbeidsflyten i Jira og GitLab gjorde det mulig Ä enkelt passere dette stadiet. MÄnedene som ble brukt eksternt viste at teamets produktivitet ikke led som et resultat; for mange Þkte komforten pÄ jobben, det eneste som manglet var direkte kommunikasjon.
Eksternt teammĂžte

MĂžter under fjernarbeid

Teknologistabel av lĂžsningen
Standard repository og CI/CD-verktÞy for X5 er GitLab. Vi bruker den til kodelagring, kontinuerlig testing og distribusjon til test- og produksjonsservere. Vi bruker ogsÄ praksisen med kodegjennomgang, nÄr minst 2 kolleger mÄ godkjenne endringer gjort av utvikleren i koden. Statiske kodeanalysatorer SonarQube og JaCoCo hjelper oss med Ä holde koden vÄr ren og sikre det nÞdvendige nivÄet av enhetstestdekning. Alle endringer i koden mÄ gÄ gjennom disse sjekkene. Alle testskript som kjÞres manuelt blir deretter automatisert.
For vellykket implementering av forretningsprosesser av "Marcus", mÄtte vi lÞse en rekke teknologiske problemer, omtrent hver i rekkefÞlge.
Oppgave 1. Behovet for horisontal skalerbarhet av systemet
For Ä lÞse dette problemet valgte vi en mikroservicetilnÊrming til arkitektur. Samtidig var det svÊrt viktig Ä forstÄ tjenestenes ansvarsomrÄde. Vi prÞvde Ä dele dem inn i forretningsdrift, med hensyn til detaljene i prosessene. For eksempel er aksept pÄ et lager ikke en veldig hyppig, men veldig storskala operasjon, der det er nÞdvendig Ä raskt fÄ informasjon fra statsregulatoren om vareenhetene som aksepteres, hvorav antallet i en levering nÄr 600000 XNUMX , sjekk om det er tillatt Ä akseptere dette produktet pÄ lageret og returner all nÞdvendig informasjon for lagerautomatiseringssystemet. Men forsendelse fra varehus har mye stÞrre intensitet, men opererer samtidig med smÄ datamengder.
Vi implementerer alle tjenester pÄ statslÞs basis og prÞver til og med Ä dele opp interne operasjoner i trinn, ved Ä bruke det vi kaller Kafka-selv-emner. Dette er nÄr en mikrotjeneste sender en melding til seg selv, som lar deg balansere belastningen pÄ mer ressurskrevende operasjoner og forenkler produktvedlikeholdet, men mer om det senere.
Vi bestemte oss for Ä dele moduler for interaksjon med eksterne systemer i separate tjenester. Dette gjorde det mulig Ä lÞse problemet med hyppig skiftende APIer for eksterne systemer, med praktisk talt ingen innvirkning pÄ tjenester med forretningsfunksjonalitet.

Alle mikrotjenester er distribuert i en OpenShift-klynge, som bÄde lÞser problemet med Ä skalere hver mikrotjeneste og lar oss ikke bruke tredjeparts tjenesteoppdagingsverktÞy.
Oppgave 2. Behovet for Ä opprettholde hÞy belastning og svÊrt intensiv datautveksling mellom plattformtjenester: Bare i lÞpet av prosjektstartfasen utfÞres ca 600 operasjoner per sekund. Vi forventer at denne verdien vil Þke til 5000 ops/sek nÄr utsalgssteder kobler seg til plattformen vÄr.
Dette problemet ble lÞst ved Ä distribuere en Kafka-klynge og nesten fullstendig forlate synkron interaksjon mellom plattformens mikrotjenester. Dette krever en svÊrt nÞye analyse av systemkravene, siden ikke alle operasjoner kan vÊre asynkrone. Samtidig overfÞrer vi ikke bare hendelser gjennom megleren, men overfÞrer ogsÄ all nÞdvendig forretningsinformasjon i meldingen. Dermed kan meldingsstÞrrelsen nÄ flere hundre kilobyte. MeldingsstÞrrelsesgrensen i Kafka krever at vi nÞyaktig forutsier meldingsstÞrrelsen, og om nÞdvendig deler vi dem, men inndelingen er logisk, relatert til forretningsdrift.
For eksempel deler vi varer som kommer i bil i esker. For synkrone operasjoner tildeles det separate mikrotjenester og det gjennomfĂžres grundig lasttesting. Ă
bruke Kafka ga oss en annen utfordring - Ä teste driften av tjenesten vÄr med tanke pÄ Kafka-integrasjonen gjÞr alle enhetstestene vÄre asynkrone. Vi lÞste dette problemet ved Ä skrive vÄre egne verktÞymetoder ved Ä bruke Embedded Kafka Broker. Dette eliminerer ikke behovet for Ä skrive enhetstester for individuelle metoder, men vi foretrekker Ä teste komplekse tilfeller ved hjelp av Kafka.
Mye oppmerksomhet ble viet til Ä spore logger slik at deres TraceId ikke skulle gÄ tapt nÄr unntak oppstÄr under driften av tjenester eller nÄr du arbeider med Kafka batch. Og hvis det ikke var noen spesielle problemer med den fÞrste, sÄ er vi i det andre tilfellet tvunget til Ä logge alle TraceId-ene som partiet fulgte med og velge en for Ä fortsette sporingen. Deretter, nÄr du sÞker med den originale TraceId, vil brukeren enkelt finne ut med hvilken sporingen fortsatte.
Oppgave 3. Behovet for Ä lagre en stor mengde data: Mer enn 1 milliard etiketter per Är for tobakk alene kommer til X5. De krever konstant og rask tilgang. Totalt mÄ systemet behandle rundt 10 milliarder registreringer av bevegelseshistorien til disse merkede varene.
For Ä lÞse det tredje problemet valgte vi NoSQL-databasen MongoDB. Vi har en shard pÄ 5 noder, og hver node har et replikasett pÄ 3 servere. Dette lar oss skalere systemet horisontalt ved Ä legge til nye servere inn i klyngen og sikre feiltoleransen. Her mÞtte vi pÄ et annet problem: Ä sikre transaksjonalitet i en Mongo-klynge mens vi brukte horisontalt skalerbare mikrotjenester. For eksempel er en av oppgavene til systemet vÄrt Ä oppdage forsÞk pÄ Ä duplisere produkter med samme merkekoder. Dette fÞrer til overlapp med feilaktige skanninger eller feilaktige kasseoperasjoner. Vi oppdaget at slike duplikater kan forekomme bÄde i en enkelt Kafka-batch som behandles og i to parallelle batcher. Derfor ga det ingen resultater Ä sjekke for duplikater ved Ä spÞrre databasen. For hver mikrotjeneste adresserte vi problemet separat basert pÄ forretningslogikken til den tjenesten. For kvitteringer la vi for eksempel til en sjekk i batchen og separat behandling for duplikater ved innsetting.
For Ă„ sikre at brukernes arbeid med driftshistorikken ikke pĂ„ noen mĂ„te pĂ„virker det viktigste â funksjonen til vĂ„re forretningsprosesser, har vi skilt alle historiske data i en egen tjeneste med en egen database, som ogsĂ„ mottar informasjon gjennom Kafka . PĂ„ denne mĂ„ten jobber brukere med en isolert tjeneste uten Ă„ pĂ„virke tjenestene som behandler data for pĂ„gĂ„ende drift.
Oppgave 4: Reprosessering og overvÄking av kÞ:
I distribuerte systemer oppstÄr det uunngÄelig problemer og feil i tilgjengeligheten av databaser, kÞer og eksterne datakilder. NÄr det gjelder Marcus, er kilden til slike feil integrasjon med eksterne systemer. Det var nÞdvendig Ä finne en lÞsning som ville tillate gjentatte forespÞrsler om feilsvar med noen spesifisert tidsavbrudd, men samtidig ikke slutte Ä behandle vellykkede forespÞrsler i hovedkÞen. For dette formÄlet ble det sÄkalte "topic based retry"-konseptet valgt. For hvert hovedemne opprettes ett eller flere gjenforsÞksemner som det sendes feilmeldinger til og samtidig elimineres forsinkelsen i behandling av meldinger fra hovedemnet. Samhandlingsplan -

For Ä implementere et slikt opplegg trengte vi fÞlgende: Ä integrere denne lÞsningen med Spring og unngÄ kodeduplisering. Mens vi surfet pÄ nettet, kom vi over en lignende lÞsning basert pÄ Spring BeanPostProccessor, men den virket unÞdvendig tungvint for oss. Teamet vÄrt har laget en enklere lÞsning som gjÞr at vi kan integreres i vÄrsyklusen for Ä skape forbrukere og i tillegg legge til Retry Consumers. Vi tilbÞd en prototype av lÞsningen vÄr til Spring-teamet, du kan se den . Antall forbrukere pÄ nytt og antall forsÞk for hver forbruker konfigureres gjennom parametere, avhengig av behovene til forretningsprosessen, og for at alt skal fungere, gjenstÄr det bare Ä legge til merknaden org.springframework.kafka.annotation.KafkaListener , som er kjent for alle Spring-utviklere.
Hvis meldingen ikke kunne behandles etter alle gjentatte forsÞk, gÄr den til DLT (dead letter topic) ved hjelp av Spring DeadLetterPublishingRecoverer. PÄ forespÞrsel fra stÞtte utvidet vi denne funksjonaliteten og opprettet en egen tjeneste som lar deg se meldinger inkludert i DLT, stackTrace, traceId og annen nyttig informasjon om dem. I tillegg ble overvÄking og varsler lagt til alle DLT-emner, og nÄ er faktisk utseendet til en melding i et DLT-emne en grunn til Ä analysere og fikse en defekt. Dette er veldig praktisk - med navnet pÄ emnet forstÄr vi umiddelbart pÄ hvilket trinn i prosessen problemet oppsto, noe som Þker sÞket etter grunnÄrsaken betydelig.

Senest har vi implementert et grensesnitt som lar oss sende meldinger pÄ nytt ved Ä bruke stÞtten vÄr etter Ä ha eliminert Ärsakene deres (for eksempel gjenoppretting av funksjonaliteten til det eksterne systemet) og, selvfÞlgelig, etablert den tilsvarende defekten for analyse. Det er her selvemnene vÄre kommer godt med: for ikke Ä starte en lang behandlingskjede pÄ nytt, kan du starte den pÄ nytt fra Þnsket trinn.

Plattformdrift
Plattformen er allerede i produktiv drift, hver dag utfĂžrer vi leveranser og forsendelser, kobler sammen nye distribusjonssentre og butikker. Som en del av piloten fungerer systemet med produktgruppene "Tobakk" og "Sko".
Hele teamet vÄrt deltar i Ä gjennomfÞre piloter, analyserer nye problemer og kommer med forslag til forbedring av produktet vÄrt, fra forbedring av logger til endring av prosesser.
For ikke Ä gjenta vÄre feil, gjenspeiles alle tilfeller funnet under piloten i automatiserte tester. TilstedevÊrelsen av et stort antall autotester og enhetstester lar deg utfÞre regresjonstesting og installere en hurtigreparasjon bokstavelig talt innen noen fÄ timer.
NÄ fortsetter vi Ä utvikle og forbedre plattformen vÄr, og mÞter stadig nye utfordringer. Hvis du er interessert, vil vi snakke om lÞsningene vÄre i de fÞlgende artiklene.
Kilde: www.habr.com
