Izkušnje pri razvoju storitve Refund Tool z asinhronim API-jem na Kafki

Kaj bi lahko prisililo tako veliko podjetje, kot je Lamoda, z racionaliziranim procesom in na desetine med seboj povezanih storitev, da bistveno spremeni svoj pristop? Motivacija je lahko popolnoma drugačna: od zakonodajne do želje po eksperimentiranju, ki je značilna za vse programerje.

A to ne pomeni, da ne morete računati na dodatne ugodnosti. Sergey Zaika vam bo povedal, kaj točno lahko osvojite, če na Kafki implementirate API, ki temelji na dogodkih (nekaj). Zagotovo bo govora tudi o velikih dosežkih in zanimivih odkritjih – brez njih eksperiment ne gre.

Izkušnje pri razvoju storitve Refund Tool z asinhronim API-jem na Kafki

Zavrnitev odgovornosti: Ta članek temelji na gradivu s srečanja, ki ga je Sergej organiziral novembra 2018 na HighLoad++. Lamodina izkušnja dela s Kafko v živo je pritegnila poslušalce nič manj kot druga poročila na sporedu. Menimo, da je to odličen primer, da se vedno da in mora najti somišljenike, organizatorji HighLoad++ pa se bodo še naprej trudili ustvarjati vzdušje, ki bo temu primerno.

O procesu

Lamoda je velika platforma za e-trgovino, ki ima svoj kontaktni center, dostavno službo (in številne podružnice), foto studio, ogromno skladišče in vse to deluje na lastni programski opremi. Obstaja na desetine načinov plačila, partnerji b2b, ki morda uporabljajo nekatere ali vse te storitve in želijo vedeti posodobljene informacije o njihovih izdelkih. Poleg tega Lamoda poleg Ruske federacije deluje še v treh državah in tam je vse nekoliko drugače. Skupno je verjetno več kot sto načinov za konfiguracijo novega naročila, ki ga je treba obdelati na svoj način. Vse to deluje s pomočjo desetin storitev, ki včasih komunicirajo na neočitne načine. Obstaja tudi centralni sistem, katerega glavna odgovornost so statusi naročil. Mi ji pravimo BOB, delam z njo.

Orodje za vračilo z API-jem, ki temelji na dogodkih

Beseda event-driven je precej otrdana, nekoliko v nadaljevanju bomo podrobneje opredelili, kaj je mišljeno s tem. Začel bom s kontekstom, v katerem smo se odločili preizkusiti pristop API-ja, ki ga vodijo dogodki, v Kafki.

Izkušnje pri razvoju storitve Refund Tool z asinhronim API-jem na Kafki

V vsaki trgovini se poleg naročil, za katera kupci plačajo, zgodijo trenutki, ko mora trgovina vrniti denar, ker izdelek stranki ni ustrezal. To je razmeroma kratek postopek: po potrebi razčistimo podatke in nakažemo denar.

Vračilo pa se je zaradi sprememb zakonodaje zapletlo in smo morali zanj uvesti ločeno mikrostoritev.

Izkušnje pri razvoju storitve Refund Tool z asinhronim API-jem na Kafki

Naša motivacija:

  1. Zakon FZ-54 - skratka, zakon zahteva poročanje davčnemu uradu o vsaki denarni transakciji, pa naj gre za vračilo ali potrdilo, v dokaj kratkem SLA, ki traja nekaj minut. Kot podjetje za e-trgovino izvajamo kar precej poslov. Tehnično to pomeni novo odgovornost (in s tem novo storitev) in izboljšave v vseh vključenih sistemih.
  2. BOB split je interni projekt podjetja za razbremenitev BOB-a velikega števila stranskih odgovornosti in zmanjšanje njegove splošne kompleksnosti.

Izkušnje pri razvoju storitve Refund Tool z asinhronim API-jem na Kafki

Ta diagram prikazuje glavne sisteme Lamoda. Zdaj jih je večina več konstelacija 5-10 mikrostoritev okoli manjšajočega se monolita. Počasi rastejo, vendar jih poskušamo zmanjšati, ker je razporeditev izbranega fragmenta na sredini strašljiva - ne smemo dovoliti, da pade. Primorani smo rezervirati vse menjave (puščice) in upoštevati dejstvo, da se katera od njih lahko izkaže za nedosegljivo.

BOB ima tudi precej menjalnic: plačilni sistemi, sistemi za dostavo, sistemi za obveščanje itd.

Tehnično je BOB:

  • ~150k vrstic kode + ~100k vrstic testov;
  • php7.2 + Zend 1 & Symfony Components 3;
  • >100 API-jev & ~50 izhodnih integracij;
  • 4 države s svojo poslovno logiko.

Uvajanje BOB je drago in boleče, količina kode in težav, ki jih rešuje, je tolikšna, da si nihče ne more vbiti vsega v glavo. Na splošno obstaja veliko razlogov za poenostavitev.

Postopek vračila

Na začetku sta v procesu vključena dva sistema: BOB in Payment. Zdaj se pojavita še dva:

  • Služba za fiskalizacijo, ki bo skrbela za težave s fiskalizacijo in komunikacijo z zunanjimi servisi.
  • Orodje za vračila, ki preprosto vsebuje nove menjave, da ne napihne BOB.

Zdaj je postopek videti takole:

Izkušnje pri razvoju storitve Refund Tool z asinhronim API-jem na Kafki

  1. BOB prejme zahtevek za vračilo.
  2. BOB govori o tem orodju za vračilo.
  3. Orodje za vračilo sporoči plačilu: "Vrni denar."
  4. Plačilo vrne denar.
  5. Refund Tool in BOB med seboj sinhronizirata statuse, saj ga zaenkrat potrebujeta oba. Nismo še pripravljeni na popoln prehod na Refund Tool, saj ima BOB UI, poročila za računovodstvo in nasploh veliko podatkov, ki jih ni mogoče tako preprosto prenesti. Sedeti je treba na dveh stolih.
  6. Zahteva za fiskalizacijo gre stran.

Posledično smo naredili nekakšen event bus na Kafko – event-bus, na katerem se je vse začelo. Hura, zdaj imamo eno samo točko napake (sarkazem).

Izkušnje pri razvoju storitve Refund Tool z asinhronim API-jem na Kafki

Prednosti in slabosti so precej očitne. Naredili smo avtobus, kar pomeni, da so zdaj vse storitve odvisne od njega. To poenostavi zasnovo, vendar v sistem uvede eno samo točko okvare. Kafka se bo zrušil, proces se bo ustavil.

Kaj je API, ki temelji na dogodkih

Dober odgovor na to vprašanje je v poročilu Martina Fowlerja (GOTO 2017) "Številni pomeni arhitekture, ki temelji na dogodkih".

Na kratko kaj smo naredili:

  1. Zaključite vse asinhrone izmenjave prek shranjevanje dogodkov. Namesto da bi vsakega zainteresiranega potrošnika obvestili o spremembi statusa preko omrežja, dogodek o spremembi statusa zapišemo v centralizirano shrambo in potrošniki, ki jih tema zanima, preberejo vse, kar se pojavi od tam.
  2. Dogodek je v tem primeru obvestilo (Obvestila), da se je nekje nekaj spremenilo. Na primer, status naročila se je spremenil. Potrošnik, ki ga zanimajo nekateri podatki ob spremembi statusa, ki niso vključeni v obvestilo, lahko sam ugotovi njihov status.
  3. Največja možnost je popolno pridobivanje dogodkov, državni prenos, v katerem dogodek vsebuje vse podatke, potrebne za obdelavo: od kod je prišel in v kakšno stanje je prišel, kako natančno so se podatki spremenili itd. Vprašanje je le izvedljivost in količina informacij, ki si jih lahko privoščite za shranjevanje.

Kot del lansiranja orodja za vračilo smo uporabili tretjo možnost. Ta poenostavljena obdelava dogodkov, saj ni bilo potrebe po pridobivanju podrobnih informacij, poleg tega pa je odpravila scenarij, kjer vsak nov dogodek ustvari množico zahtev za razjasnitev pridobitve od potrošnikov.

Storitev orodja za vračilo ni naložen, zato je Kafka bolj okus peresa kot nuja. Mislim, da podjetje ne bi bilo srečno, če bi storitev vračila postala projekt z visoko obremenitvijo.

Asinhrona izmenjava KOT JE

Za asinhrone izmenjave PHP oddelek običajno uporablja RabbitMQ. Podatke za zahtevo smo zbrali, jih postavili v čakalno vrsto, uporabnik iste storitve pa jih je prebral in poslal (oz. ni poslal). Za sam API Lamoda aktivno uporablja Swagger. Oblikujemo API, ga opišemo v Swaggerju in ustvarimo kodo odjemalca in strežnika. Uporabljamo tudi nekoliko izboljšan JSON RPC 2.0.

Ponekod se uporabljajo vodila ESB, nekatera živijo na activeMQ, vendar na splošno RabbitMQ - standard.

Asinhrona izmenjava BODE

Pri načrtovanju izmenjave preko event-busa je mogoče zaslediti analogijo. Podobno opisujemo prihodnjo izmenjavo podatkov z opisi strukture dogodkov. Format yaml, generiranje kode smo morali narediti sami, generator ustvari DTO po specifikaciji in nauči odjemalce in strežnike dela z njimi. Generacija gre v dva jezika - golang in php. To pomaga ohranjati doslednost knjižnic. Generator je napisan v golangu, zato je dobil ime gogi.

Dogodki o Kafki so tipična stvar. Obstaja rešitev iz glavne poslovne različice Kafka Confluent, obstaja nakadi, rešitev iz naše domene bratov Zalando. Naš motivacija za začetek z vanilijevim Kafko - to pomeni, da pustimo rešitvi prosto pot, dokler se dokončno ne odločimo, ali jo bomo uporabljali povsod, ter si pustimo manevrski prostor in izboljšave: želimo podporo za naše JSON RPC 2.0, generatorji za dva jezika in poglejmo še kaj.

Ironično je, da tudi v tako srečnem primeru, ko obstaja približno podoben posel, Zalando, ki je naredil približno podobno rešitev, tega ne moremo učinkovito uporabiti.

Arhitekturni vzorec ob lansiranju je naslednji: beremo neposredno od Kafke, pišemo pa le prek event-busa. Pri Kafki je marsikaj pripravljenega za branje: posredniki, balanserji, bolj ali manj je pripravljeno za horizontalno skaliranje, to sem hotel obdržati. Želeli smo dokončati snemanje prek enega prehoda, imenovanega Events-bus, in tukaj je razlog.

Dogodki-bus

Ali prireditveni avtobus. To je preprosto http prehod brez stanja, ki ima več pomembnih vlog:

  • Izdelava validacije — preverjamo, ali dogodki ustrezajo našim specifikacijam.
  • Glavni sistem dogodkov, torej je to glavni in edini sistem v podjetju, ki odgovarja na vprašanje, kateri dogodki s katerimi strukturami veljajo. Validacija preprosto vključuje tipe podatkov in enume za natančno določanje vsebine.
  • Zgoščevalna funkcija za razčlenjevanje - struktura Kafkinega sporočila je ključ-vrednost in z zgoščevanjem ključa se izračuna, kam ga postaviti.

Zakaj

Delamo v velikem podjetju z urejenim procesom. Zakaj karkoli spreminjati? To je poskus, in pričakujemo, da bomo izkoristili številne koristi.

Izmenjave 1:n+1 (ena proti več)

Kafka omogoča zelo preprosto povezovanje novih potrošnikov z API-jem.

Recimo, da imate imenik, ki ga morate posodabljati v več sistemih hkrati (in v nekaterih novih). Prej smo izumili sveženj, ki je izvajal set-API, glavni sistem pa je bil obveščen o naslovih potrošnikov. Zdaj glavni sistem pošilja posodobitve teme in vsi, ki jih zanima, to preberejo. Pojavil se je nov sistem - prijavili smo ga na temo. Da, tudi sveženj, vendar preprostejši.

V primeru orodja za vračilo, ki je del BOB, je priročno, da jih sinhroniziramo prek Kafke. Plačilo pravi, da je bil denar vrnjen: BOB, RT so za to izvedeli, spremenili statuse, za to je izvedel servis za fiskalizacijo in izdal ček.

Izkušnje pri razvoju storitve Refund Tool z asinhronim API-jem na Kafki

V načrtu imamo vzpostavitev enotne storitve obveščanja, ki bi naročnika obveščala o novostih glede njegovega naročila/vračil. Zdaj je ta odgovornost porazdeljena med sistemi. Dovolj bo, da obvestilno storitev naučimo, da ujame ustrezne informacije iz Kafke in se nanje odzove (in ta obvestila onemogočimo v drugih sistemih). Nove neposredne izmenjave ne bodo potrebne.

Na podlagi podatkov

Informacije med sistemi postanejo pregledne - ne glede na to, kakšno "krvavo podjetje" imate in ne glede na to, kako velike so vaše zaostanke. Lamoda ima oddelek za podatkovno analitiko, ki zbira podatke iz sistemov in jih daje v obliko za večkratno uporabo, tako za poslovne kot za inteligentne sisteme. Kafka vam omogoča, da jim hitro posredujete veliko podatkov in ta pretok informacij posodabljate.

Dnevnik podvajanja

Sporočila po branju ne izginejo, kot v RabbitMQ. Ko dogodek vsebuje dovolj informacij za obdelavo, imamo zgodovino nedavnih sprememb objekta in po želji možnost uporabe teh sprememb.

Obdobje shranjevanja dnevnika replikacije je odvisno od intenzivnosti pisanja v to temo; Kafka vam omogoča prilagodljivo nastavitev omejitev časa shranjevanja in količine podatkov. Pri intenzivnih temah je pomembno, da imajo vsi potrošniki čas prebrati informacije, preden izginejo, tudi v primeru kratkotrajne nedelovanja. Običajno je mogoče shraniti podatke za enote dni, kar je povsem dovolj za podporo.

Izkušnje pri razvoju storitve Refund Tool z asinhronim API-jem na Kafki

Sledi še malo ponovnega pripovedovanja dokumentacije, za tiste, ki Kafke ne poznate (slika je tudi iz dokumentacije)

AMQP ima čakalne vrste: v čakalno vrsto pišemo sporočila za potrošnika. Običajno eno čakalno vrsto obdeluje en sistem z isto poslovno logiko. Če morate obvestiti več sistemov, lahko aplikacijo naučite pisati v več čakalnih vrst ali konfigurirate izmenjavo z mehanizmom fanout, ki jih sam klonira.

Kafka ima podobno abstrakcijo temo, v katerega pišete sporočila, ki pa po branju ne izginejo. Privzeto, ko se povežete s Kafko, prejmete vsa sporočila in imate možnost, da shranite tam, kjer ste končali. To pomeni, da berete zaporedno, sporočila ne smete označiti kot prebrano, ampak shranite ID, s katerega lahko nadaljujete z branjem. Id, za katerega ste se odločili, se imenuje odmik, mehanizem pa je odmik potrditve.

V skladu s tem se lahko izvaja drugačna logika. Na primer, imamo BOB v 4 primerih za različne države - Lamoda je v Rusiji, Kazahstanu, Ukrajini, Belorusiji. Ker so razporejeni ločeno, imajo nekoliko drugačne konfiguracije in lastno poslovno logiko. V sporočilu navedemo, za katero državo se nanaša. Vsak porabnik BOB v vsaki državi bere z drugačnim groupId, in če sporočilo zanj ne velja, ga preskoči, tj. takoj izvede odmik +1. Če isto temo bere naša plačilna služba, potem to počne z ločeno skupino, zato se poboti ne sekajo.

Zahteve za dogodek:

  • Popolnost podatkov. Želim, da ima dogodek dovolj podatkov, da ga je mogoče obdelati.

  • Celovitost Na Events-bus prenesemo preverjanje, ali je dogodek skladen in ga lahko obdela.
  • Vrstni red je pomemben. V primeru vrnitve smo prisiljeni delati z zgodovino. Pri obvestilih vrstni red ni pomemben, če gre za homogena obvestila, bo e-pošta enaka ne glede na to, katero naročilo je prvo prispelo. V primeru vračila je jasen postopek, če spremenimo naročilo, se pojavijo izjeme, vračilo ne bo ustvarjeno ali obdelano - na koncu bomo v drugem statusu.
  • Doslednost. Imamo trgovino in zdaj ustvarjamo dogodke namesto API-ja. Potrebujemo način za hitro in poceni posredovanje informacij o novih dogodkih in spremembah obstoječih v naše storitve. To se doseže s skupno specifikacijo v ločenem repozitoriju git in generatorji kode. Zato so odjemalci in strežniki v različnih storitvah usklajeni.

Kafka v Lamodi

Imamo tri Kafkine instalacije:

  1. hlodi;
  2. R&R;
  3. Dogodki-bus.

Danes govorimo samo o zadnji točki. Pri dogodkih-busu nimamo zelo velikih instalacij - 3 posredniki (strežniki) in samo 27 tem. Praviloma je ena tema en proces. Toda to je subtilna točka in zdaj se je bomo dotaknili.

Izkušnje pri razvoju storitve Refund Tool z asinhronim API-jem na Kafki

Zgoraj je graf rps. Postopek vračila je označen s turkizno črto (da, tisto na X osi), roza črta pa je postopek posodobitve vsebine.

Katalog Lamoda vsebuje na milijone izdelkov, podatki pa se ves čas posodabljajo. Nekatere kolekcije gredo iz mode, nadomeščajo jih nove, v katalogu pa se nenehno pojavljajo novi modeli. Trudimo se predvideti, kaj bo našim kupcem zanimivo jutri, zato nenehno nabavljamo nove stvari, jih fotografiramo in posodabljamo vitrino.

Rožnati vrhovi so posodobitve izdelkov, torej spremembe izdelkov. Se vidi, da so se fantje slikali, slikali, pa še enkrat! — naložen paket dogodkov.

Primeri uporabe Lamoda Events

Zgrajeno arhitekturo uporabljamo za naslednje operacije:

  • Sledenje statusu vračila: poziv k dejanju in sledenje statusu iz vseh vključenih sistemov. Plačilo, statusi, fiskalizacija, obvestila. Tu smo preizkusili pristop, naredili orodja, zbrali vse hrošče, napisali dokumentacijo in sodelavcem povedali, kako jo uporabljati.
  • Posodabljanje kartic izdelkov: konfiguracija, metapodatki, značilnosti. En sistem bere (ki prikazuje), več jih piše.
  • E-pošta, push in sms: naročilo je bilo prevzeto, naročilo je prispelo, vračilo je bilo sprejeto itd., veliko jih je.
  • Zaloga, obnova skladišča — kvantitativna posodobitev artiklov, samo številke: prihod v skladišče, vračilo. Nujno je, da vsi sistemi, povezani z rezervacijo blaga, delujejo z najnovejšimi podatki. Trenutno je sistem posodabljanja delnic precej zapleten, Kafka ga bo poenostavil.
  • Analiza podatkov (oddelek za raziskave in razvoj), orodja ML, analitika, statistika. Želimo, da so informacije pregledne – Kafka je zelo primeren za to.

Zdaj pa bolj zanimiv del o velikih udarcih in zanimivih odkritjih, ki so se zgodili v zadnjih šestih mesecih.

Težave z zasnovo

Recimo, da želimo narediti novo stvar – na primer prenesti celoten postopek dostave v Kafko. Zdaj je del procesa implementiran v Obdelavo naročil v BOB. Za prenosom naročila v dostavno službo, premikom v vmesno skladišče ipd. je statusni model. Obstaja cel monolit, celo dva, plus kup API-jev, namenjenih dostavi. O dostavi vedo veliko več.

Zdi se, da gre za podobna področja, vendar imata obdelava naročil v BOB in sistem pošiljanja različna statusa. Na primer, nekatere kurirske službe ne pošiljajo vmesnih statusov, ampak samo končne: "dostavljeno" ali "izgubljeno". Drugi, nasprotno, zelo podrobno poročajo o pretoku blaga. Vsak ima svoja pravila preverjanja: za nekatere je e-pošta veljavna, kar pomeni, da bo obdelana; za druge ne velja, ampak bo naročilo vseeno obdelano, ker je telefonska številka za kontakt, pa bo kdo rekel, da tako naročilo sploh ne bo obdelano.

Tok podatkov

V primeru Kafke se postavlja vprašanje organizacije pretoka podatkov. Ta naloga vključuje izbiro strategije na podlagi več točk; pojdimo skozi vse.

V eni temi ali v različnih?

Imamo specifikacijo dogodka. V BOB zapišemo, da je potrebno takšno in takšno naročilo dostaviti, ter navedemo: številko naročila, njegovo sestavo, nekatere SKU in črtne kode itd. Ko bo blago prispelo v skladišče, bo dostava lahko prejela statuse, časovne žige in vse, kar je potrebno. Toda potem želimo prejemati posodobitve teh podatkov v BOB. Imamo obratni postopek prejemanja podatkov iz dostave. Je to isti dogodek? Ali pa je to ločena izmenjava, ki si zasluži svojo temo?

Najverjetneje si bodo zelo podobni in skušnjava, da bi naredili eno temo, ni neutemeljena, saj ločena tema pomeni ločene porabnike, ločene konfiguracije, ločeno generacijo vsega tega. Ampak ne dejstvo.

Novo področje ali nov dogodek?

Če pa uporabljate iste dogodke, se pojavi še en problem. Na primer, vsi dostavni sistemi ne morejo ustvariti vrste DTO, kot jo lahko ustvari BOB. ID jim pošljemo, vendar ga ne shranijo, ker ga ne potrebujejo, in z vidika zagona procesa event-bus je to polje obvezno.

Če uvedemo pravilo za vodilo dogodkov, da je to polje obvezno, potem smo prisiljeni nastaviti dodatna pravila preverjanja v BOB ali v obdelovalniku začetnega dogodka. Validacija se začne širiti po storitvi - to ni zelo priročno.

Druga težava je skušnjava po postopnem razvoju. Rečeno nam je, da je treba dogodku nekaj dodati in morda bi moral biti, če dobro pomislimo, poseben dogodek. Toda v naši shemi je ločen dogodek ločena tema. Ločena tema je celoten postopek, ki sem ga opisal zgoraj. Razvijalec je v skušnjavi, da preprosto doda še eno polje v shemo JSON in ga znova ustvari.

Pri vračilih smo na dogodek prišli v pol leta. Imeli smo en metadogodek, imenovan posodobitev povračila, ki je vseboval polje tipa, ki je opisovalo, kakšna je ta posodobitev. Zaradi tega smo imeli »čudovita« stikala z validatorji, ki so nam povedali, kako preveriti ta dogodek s to vrsto.

Verzija dogodkov

Za preverjanje sporočil v Kafki lahko uporabite Avro, vendar se je bilo treba takoj uleči in uporabiti Confluent. V našem primeru moramo biti previdni pri različicah. Ne bo vedno mogoče znova prebrati sporočil iz dnevnika replikacije, ker je model "zapustil". V bistvu se izkaže, da gradimo različice tako, da je model nazaj združljiv: na primer, naredite polje začasno neobvezno. Če so razlike premočne, začnemo pisati v novi temi, stranke pa prenesemo, ko preberejo staro.

Zagotovljen vrstni red branja particij

Teme znotraj Kafke so razdeljene na particije. To ni zelo pomembno, ko načrtujemo entitete in izmenjave, vendar je pomembno, ko se odločamo, kako to porabiti in povečati.

V običajnem primeru pišete eno temo v Kafki. Privzeto je uporabljena ena particija in vsa sporočila v tej temi gredo vanjo. In potrošnik posledično ta sporočila bere zaporedno. Recimo, da moramo zdaj razširiti sistem, tako da sporočila bereta dva različna porabnika. Če na primer pošiljate SMS, potem lahko rečete Kafki, naj naredi dodatno particijo, in Kafka bo sporočila začela deliti na dva dela - pol tukaj, pol tukaj.

Kako jih deli Kafka? Vsako sporočilo ima telo (v katerem shranimo JSON) in ključ. Temu ključu lahko priložite zgoščevalno funkcijo, ki bo določila, v katero particijo bo šlo sporočilo.

V našem primeru z vračili je to pomembno, če vzamemo dve particiji, potem obstaja možnost, da bo vzporedni potrošnik obdelal drugi dogodek pred prvim in bodo težave. Funkcija zgoščevanja zagotavlja, da sporočila z istim ključem končajo v isti particiji.

Dogodki proti ukazom

To je še ena težava, na katero smo naleteli. Dogodek je določen dogodek: pravimo, da se je nekje nekaj zgodilo (something_happened), na primer, je bil artikel odpovedan ali je prišlo do vračila denarja. Če nekdo prisluhne tem dogodkom, bo v skladu z "item cancelled" ustvarjena entiteta za vračilo in "vračilo je prišlo" bo zapisano nekje v nastavitvah.

Toda običajno, ko načrtujete dogodke, jih ne želite pisati zaman - zanašate se na to, da jih bo nekdo prebral. Obstaja velika skušnjava, da ne bi napisali nekaj_se_zgodilo (predmet_preklican, vračilo_vrnjeno), ampak nekaj_bi_se_storilo. Na primer, izdelek je pripravljen za vračilo.

Po eni strani nakazuje, kako bo dogodek uporabljen. Po drugi strani pa zveni veliko manj kot običajno ime dogodka. Poleg tega ni daleč od tu do ukaza do_something. Vendar nimate nobenega zagotovila, da je nekdo prebral ta dogodek; in če jo bereš, potem si jo uspešno prebral; in če ste ga uspešno prebrali, potem ste nekaj naredili in to nekaj je bilo uspešno. V trenutku, ko dogodek postane do_something, postane povratna informacija potrebna in to je problem.

Izkušnje pri razvoju storitve Refund Tool z asinhronim API-jem na Kafki

Pri asinhroni izmenjavi v RabbitMQ, ko preberete sporočilo, pojdite na http, imate odgovor - vsaj to, da je bilo sporočilo prejeto. Ko pišete Kafki, je sporočilo, ki ste ga napisali Kafki, vendar ne veste ničesar o tem, kako je bilo obdelano.

Zato smo morali v našem primeru uvesti odzivni dogodek in nastaviti monitoring tako, da če je bilo poslanih toliko dogodkov, po takem in takem času prispe enako število odzivnih dogodkov. Če se to ne zgodi, se zdi, da je šlo nekaj narobe. Na primer, če smo poslali dogodek »item_ready_to_refund«, pričakujemo, da bo ustvarjeno vračilo, denar bo vrnjen stranki in dogodek »money_refunded« bo poslan nam. Vendar to ni gotovo, zato je potrebno spremljanje.

Ponudbe

Obstaja dokaj očiten problem: če zaporedno berete od teme in imate slabo sporočilo, bo potrošnik padel in ne boste šli dlje. Potrebujete zaustaviti vse potrošnike, za nadaljevanje branja naredite odmik naprej.

Vedeli smo za to, računali smo na to, pa se je vendarle zgodilo. In to se je zgodilo, ker je bil dogodek veljaven z vidika vodila dogodkov, dogodek je bil veljaven z vidika validatorja aplikacij, vendar ni bil veljaven z vidika PostgreSQL, ker v našem enem sistemu MySQL z UNSIGNED INT, v novonapisanem pa je imel sistem PostgreSQL samo z INT. Njegova velikost je nekoliko manjša in Id ni ustrezal. Symfony je z izjemo umrl. Seveda smo ujeli izjemo, ker smo se zanašali nanjo in nameravali izvesti ta popravek, vendar smo pred tem želeli povečati števec težav, ker je bilo sporočilo obdelano neuspešno. Tudi števci v tem projektu so v bazi podatkov in Symfony je že prekinil komunikacijo z bazo podatkov, druga izjema pa je uničila celoten proces brez možnosti, da bi izvedel popravek.

Storitev je nekaj časa mirovala - na srečo pri Kafki to ni tako slabo, saj sporočila ostanejo. Ko je delo obnovljeno, jih lahko končate z branjem. Udobno je.

Kafka ima možnost nastavitve poljubnega odmika z orodjem. Toda za to morate ustaviti vse potrošnike - v našem primeru pripravite ločeno izdajo, v kateri ne bo potrošnikov, prerazporeditev. Nato lahko v Kafki premaknete odmik z orodjem in sporočilo bo šlo skozi.

Še en odtenek - dnevnik podvajanja proti rdkafka.so - je povezano s specifiko našega projekta. Uporabljamo PHP in v PHP praviloma vse knjižnice komunicirajo s Kafko prek repozitorija rdkafka.so, potem pa obstaja nekakšen ovoj. Mogoče so to naše osebne težave, a izkazalo se je, da preprosto ponovno branje delčka tega, kar smo že prebrali, ni tako enostavno. Na splošno so bile težave s programsko opremo.

Če se vrnemo k posebnostim dela s particijami, je zapisano prav v dokumentaciji potrošniki >= particije tem. A za to sem izvedel veliko pozneje, kot bi si želel. Če želite skalirati in imeti dva porabnika, potrebujete vsaj dve particiji. Se pravi, če ste imeli eno particijo, v kateri se je nabralo 20 tisoč sporočil, in ste naredili novo, se število sporočil ne bo kmalu izenačilo. Če želite torej imeti dva vzporedna porabnika, se morate ukvarjati s particijami.

Spremljanje

Mislim, da bo tako, kot bomo spremljali, še bolj jasno, kakšne težave so v obstoječem pristopu.

Na primer, izračunamo, koliko izdelkov v bazi podatkov je nedavno spremenilo svoj status, in v skladu s tem bi se morali zgoditi dogodki na podlagi teh sprememb, in to številko pošljemo v naš nadzorni sistem. Nato od Kafke dobimo drugo številko, koliko dogodkov je bilo dejansko zabeleženih. Očitno mora biti razlika med tema dvema številkama vedno nič.

Izkušnje pri razvoju storitve Refund Tool z asinhronim API-jem na Kafki

Poleg tega morate spremljati, kako gre proizvajalcu, ali je event-bus prejel sporočila in kako gre potrošniku. Na spodnjih grafikonih je na primer orodje za vračilo dobro, vendar ima BOB očitno nekaj težav (modri vrhovi).

Izkušnje pri razvoju storitve Refund Tool z asinhronim API-jem na Kafki

Omenil sem že zaostanek potrošniške skupine. Grobo rečeno, to je število neprebranih sporočil. Na splošno naši potrošniki delujejo hitro, zato je zamik običajno 0, včasih pa lahko pride do kratkotrajnega vrha. Kafka lahko to naredi takoj, vendar morate nastaviti določen interval.

Obstaja projekt burrowki vam bo dal več informacij o Kafki. Preprosto uporablja API skupine potrošnikov, da poda status, kako ta skupina deluje. Poleg OK in Failed je opozorilo in lahko ugotovite, da vaši potrošniki niso kos tempu proizvodnje - nimajo časa lektorirati napisanega. Sistem je precej pameten in enostaven za uporabo.

Izkušnje pri razvoju storitve Refund Tool z asinhronim API-jem na Kafki

Tako je videti odgovor API-ja. Tukaj je skupina bob-live-fifa, particija refund.update.v1, status OK, zamik 0 - zadnji končni odmik tak in tak.

Izkušnje pri razvoju storitve Refund Tool z asinhronim API-jem na Kafki

Spremljanje posodobljeno_v SLA (zataknjeno) Sem že omenil. Na primer, izdelek se je spremenil v status, da je pripravljen za vračilo. Namestimo Cron, ki pravi, da če ta predmet ni šel na vračilo v 5 minutah (denar vrnemo prek plačilnih sistemov zelo hitro), je nekaj zagotovo šlo narobe in to je vsekakor primer za podporo. Zato preprosto vzamemo Cron, ki take stvari prebere in če so večje od 0, potem pošlje opozorilo.

Če povzamem, uporaba dogodkov je priročna, ko:

  • informacije potrebuje več sistemov;
  • rezultat obdelave ni pomemben;
  • dogodkov je malo ali majhnih dogodkov.

Zdi se, da ima članek zelo specifično temo - asinhroni API na Kafki, vendar bi v zvezi z njim rad priporočil veliko stvari hkrati.
Prvi, naslednji HighLoad ++ počakati moramo do novembra; aprila bo različica iz Sankt Peterburga, junija pa bomo govorili o visokih obremenitvah v Novosibirsku.
Drugič, avtor poročila Sergej Zaika je član programskega odbora naše nove konference o upravljanju znanja. KnowledgeConf. Konferenca je enodnevna, potekala bo 26. aprila, vendar je njen program zelo intenziven.
In maja bo PHP Rusija и RIT++ (z vključenim DevOpsConfom) - tam lahko tudi predlagate svojo temo, govorite o svojih izkušnjah in se pritožujete nad svojimi polnjenimi stožci.

Vir: www.habr.com

Dodaj komentar