"Walking in my shoes" - vent, er de merket?

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.

"Walking in my shoes" - vent, er de merket?

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

"Walking in my shoes" - vent, er de merket?

Møter under fjernarbeid

"Walking in my shoes" - vent, er de merket?

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.

"Walking in my shoes" - vent, er de merket?

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 ble NoSQL-databasen MongoDB valgt. Vi har bygget et skjær av 5 noder og hver node har et replikasett med 3 servere. Dette lar deg skalere systemet horisontalt, legge til nye servere til klyngen og sikre dets feiltoleranse. Her møtte vi et annet problem - å sikre transaksjonalitet i mongo-klyngen, tatt i betraktning bruken av horisontalt skalerbare mikrotjenester. For eksempel er en av oppgavene til systemet vårt å identifisere forsøk på å videreselge produkter med de samme merkekodene. Her vises overlegg med feilskanning eller feiloperasjoner av kasserere. Vi fant at slike duplikater kan forekomme både innenfor én Kafka-batch som behandles, og innen to batcher som behandles parallelt. Derfor ga det ikke noe å se etter duplikater ved å spørre i databasen. For hver mikrotjeneste løste vi problemet separat basert på forretningslogikken til denne tjenesten. For sjekker har vi for eksempel lagt til en sjekk i batch og separat behandling for utseendet til 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 -

"Walking in my shoes" - vent, er de merket?

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 her. 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.

"Walking in my shoes" - vent, er de merket?

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.

"Walking in my shoes" - vent, er de merket?

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

Legg til en kommentar