Kogemused Kafka asünkroonse API-ga tagastustööriista teenuse arendamisel

Mis võiks sundida nii suurt ettevõtet nagu Lamoda, millel on tõhus protsess ja kümned omavahel seotud teenused, oma lähenemist oluliselt muutma? Motivatsioon võib olla täiesti erinev: alates seadusandlikust kuni katsetamissoovini, mis on omane kõigile programmeerijatele.

Kuid see ei tähenda, et te ei saa loota lisahüvedele. Sergey Zaika ütleb teile, mida täpselt võite võita, kui rakendate sündmustepõhise API Kafkas (vähesald). Kindlasti tuleb juttu ka suurtest võtetest ja huvitavatest avastustest – ilma nendeta eksperiment läbi ei saa.

Kogemused Kafka asünkroonse API-ga tagastustööriista teenuse arendamisel

Kohustustest loobumine: see artikkel põhineb materjalidel, mis pärinevad Sergei 2018. aasta novembris saidil HighLoad++ peetud kohtumisest. Lamoda live-kogemus Kafkaga töötamisel meelitas kuulajaid mitte vähem kui teised kavas olevad aruanded. Meie arvates on see suurepärane näide sellest, et mõttekaaslasi võib ja tuleb alati leida ning HighLoad++ korraldajad püüavad ka edaspidi luua seda soodustavat õhkkonda.

Protsessi kohta

Lamoda on suur e-kaubanduse platvorm, millel on oma kontaktkeskus, kohaletoimetamisteenus (ja palju sidusettevõtteid), fotostuudio, tohutu ladu ning see kõik töötab oma tarkvaral. On kümneid makseviise, b2b-partnereid, kes võivad kasutada mõnda või kõiki neid teenuseid ja soovivad saada ajakohast teavet oma toodete kohta. Lisaks tegutseb Lamoda peale Venemaa Föderatsiooni kolmes riigis ja seal on kõik veidi teistmoodi. Kokku on uue tellimuse seadistamiseks ilmselt üle saja võimaluse, mida tuleb omal moel töödelda. Kõik see toimib kümnete teenuste abil, mis mõnikord suhtlevad ebaselgelt. Samuti on olemas kesksüsteem, mille põhivastutus on tellimuste staatused. Me kutsume teda TP-ks, ma töötan temaga.

Tagasimakse tööriist sündmustepõhise API-ga

Sõna sündmustest juhitud on üsna hakitud, veidi edasi defineerime täpsemalt, mida selle all mõeldakse. Alustan kontekstist, milles otsustasime proovida sündmustepõhist API-lähenemist Kafkas.

Kogemused Kafka asünkroonse API-ga tagastustööriista teenuse arendamisel

Igas poes tuleb lisaks tellimustele, mille eest kliendid maksavad, kordi, kus kauplus on kohustatud raha tagastama, kuna toode kliendile ei sobinud. See on suhteliselt lühike protsess: vajadusel täpsustame infot ja kanname raha üle.

Aga tagastamine muutus seadusandluse muudatuste tõttu keerulisemaks ja selleks tuli rakendada eraldi mikroteenus.

Kogemused Kafka asünkroonse API-ga tagastustööriista teenuse arendamisel

Meie motivatsioon:

  1. Seadus FZ-54 - ühesõnaga seadus nõuab üsna lühikese, mõneminutilise SLA jooksul igast rahatehingust, olgu see siis tagastus või kviitung, maksuametile aru andmist. Meie kui e-kaubandusettevõte teeme päris palju toiminguid. Tehniliselt tähendab see uut vastutust (ja seega ka uut teenust) ja kõigi kaasatud süsteemide täiustusi.
  2. TP jagamine on ettevõtte siseprojekt, mille eesmärk on vabastada TP paljudest mittepõhikohustustest ja vähendada selle üldist keerukust.

Kogemused Kafka asünkroonse API-ga tagastustööriista teenuse arendamisel

See diagramm näitab peamisi Lamoda süsteeme. Nüüd on enamik neist rohkem 5-10 mikroteenusest koosnev tähtkuju kahaneva monoliidi ümber. Need kasvavad aeglaselt, kuid proovime neid väiksemaks muuta, sest keskel valitud fragmendi juurutamine on hirmutav – me ei saa lubada, et see kukub. Oleme sunnitud reserveerima kõik vahetused (nooled) ja arvestama asjaoluga, et mõni neist võib osutuda kättesaamatuks.

BOB-l on ka päris palju vahetusi: maksesüsteemid, tarnesüsteemid, teavitussüsteemid jne.

Tehniliselt TP on:

  • ~150k koodirida + ~100k rida teste;
  • php7.2 + Zend 1 ja Symfony Components 3;
  • >100 API-d ja ~50 väljaminevat integratsiooni;
  • 4 riiki oma äriloogikaga.

BOBi juurutamine on kallis ja valus, koodi ja lahendatavate probleemide hulk on selline, et keegi ei suuda seda kõike endale pähe panna. Üldiselt on selle lihtsustamiseks palju põhjusi.

Tagastamisprotsess

Algselt on protsessi kaasatud kaks süsteemi: BOB ja Payment. Nüüd ilmub veel kaks:

  • Fiskaliseerimisteenus, mis hoolitseb maksustamise ja välisteenustega suhtlemise probleemide eest.
  • Refund Tool, mis sisaldab lihtsalt uusi vahetusi, et mitte tõsta TP-d.

Nüüd näeb protsess välja selline:

Kogemused Kafka asünkroonse API-ga tagastustööriista teenuse arendamisel

  1. BOB saab tagasimaksetaotluse.
  2. BOB räägib sellest tagasimakse tööriistast.
  3. Tagasimakse tööriist ütleb maksele: "Tagasta raha."
  4. Tasumine tagastab raha.
  5. Refund Tool ja BOB sünkroonivad olekud üksteisega, sest praegu vajavad nad mõlemad seda. Me ei ole veel valmis täielikult tagasimakse tööriistale üle minema, kuna BOB-il on kasutajaliides, raamatupidamisaruanded ja üldiselt palju andmeid, mida ei saa nii lihtsalt üle kanda. Peate istuma kahel toolil.
  6. Fiskaliseerimistaotlus kaob.

Selle tulemusena tegime Kafkale omamoodi üritusbussi - üritus-buss, millest kõik alguse sai. Hurraa, nüüd on meil üksainus ebaõnnestumise punkt (sarkasm).

Kogemused Kafka asünkroonse API-ga tagastustööriista teenuse arendamisel

Plussid ja miinused on üsna ilmsed. Tegime bussi, mis tähendab, et nüüd sõltuvad kõik teenused sellest. See lihtsustab disaini, kuid toob süsteemi ühe rikkepunkti. Kafka jookseb kokku, protsess peatub.

Mis on sündmustepõhine API

Hea vastus sellele küsimusele on Martin Fowleri raportis (GOTO 2017) "Sündmustest juhitud arhitektuuri paljud tähendused".

Lühidalt, mida me tegime:

  1. Lõpetage kõik asünkroonsed vahetused kaudu sündmuste salvestamine. Selle asemel, et teavitada igat huvilist tarbijat olekumuutusest üle võrgu, kirjutame tsentraliseeritud salvestusruumi olekumuutusest sündmuse ning teemast huvitatud tarbijad loevad kõike, mis sealt ilmub.
  2. Sel juhul on sündmuseks teade (teated), et midagi on kuskil muutunud. Näiteks tellimuse olek on muutunud. Tarbija, kes on huvitatud mõnest staatusemuutusega kaasnevast ja teatises mitteolevast teabest, saab selle oleku ise teada.
  3. Maksimaalne võimalus on täieõiguslik sündmuste hankimine, riigi üleandmine, mille puhul sisaldab kogu töötlemiseks vajalikku teavet: kust see tuli ja millisesse olekusse läks, kuidas täpselt andmed muutusid jne. Küsimus on vaid otstarbekuses ja teabe mahus, mida saate endale lubada salvestada.

Tagasimakse tööriista käivitamise osana kasutasime kolmandat võimalust. See lihtsustas sündmuste töötlemist, kuna puudus vajadus üksikasjaliku teabe väljavõtmiseks, lisaks välistas stsenaariumi, kus iga uus sündmus genereerib tarbijate selgitustaotluste puhangu.

Tagasimakse tööriista teenus laadimata, nii et Kafka on pigem pastaka maitse kui vajadus. Ma ei usu, et kui tagasimakseteenusest saaks suure koormusega projekt, oleks äri rahul.

Asünkroonvahetus NAGU ON

Asünkroonsete vahetuste jaoks kasutab PHP osakond tavaliselt RabbitMQ-d. Kogusime päringu jaoks andmed, panime need järjekorda ning sama teenuse tarbija luges need läbi ja saatis (või ei saatnud). API enda jaoks kasutab Lamoda aktiivselt Swaggerit. Kujundame API, kirjeldame seda Swaggeris ning genereerime kliendi- ja serverikoodi. Kasutame ka veidi täiustatud JSON RPC 2.0.

Mõnes kohas kasutatakse ESB busse, mõned elavad ActiveMQ-l, kuid üldiselt RabbitMQ - standardne.

Asünkroonvahetus OLEMAS

Ürituste-bussi vahendusel vahetust kavandades saab jälgida analoogiat. Sarnaselt kirjeldame tulevast andmevahetust sündmuste struktuuri kirjelduste kaudu. Yaml formaat, koodi genereerimise pidime ise tegema, generaator loob DTOd vastavalt spetsifikatsioonile ja õpetab kliente ja servereid nendega töötama. Põlvkond läheb kahte keelde - golang ja php. See aitab hoida raamatukogusid järjepidevana. Generaator on kirjutatud golangi keeles, mistõttu sai see nime gogi.

Kafka sündmuste hankimine on tüüpiline asi. Kafka Confluenti peamisest ettevõtteversioonist on lahendus olemas nakadi, lahendus meie domeenivendadelt Zalandolt. Meie motivatsioon alustada vanilje Kafkaga - see tähendab lahenduse vabaks jätmist seni, kuni lõpuks otsustame, kas kasutame seda igal pool, ning ka endale manööverdamis- ja täiustusruumi jätmist: tahame omale tuge JSON RPC 2.0, generaatorid kahe keele jaoks ja vaatame, mida veel.

On irooniline, et isegi sellisel õnnelikul juhul, kui on umbes sarnane äri, Zalando, kes tegi umbes sarnase lahenduse, ei saa me seda tõhusalt kasutada.

Käivitamisel on arhitektuurne muster järgmine: loeme otse Kafkast, aga kirjutame ainult sündmuste-bussi kaudu. Kafkas on palju lugemiseks valmis: maaklerid, tasakaalustajad ja see on enam-vähem valmis horisontaalseks skaleerimiseks, tahtsin seda säilitada. Tahtsime salvestuse lõpule viia ühe Gateway ehk Events-busi kaudu ja siin on põhjus.

Üritused-buss

Või ürituste buss. See on lihtsalt olekuta http-lüüs, millel on mitu olulist rolli:

  • Valideerimise valmistamine — kontrollime, kas üritused vastavad meie nõuetele.
  • Sündmuste põhisüsteem, ehk see on peamine ja ainus süsteem ettevõttes, mis vastab küsimusele, millised sündmused milliste struktuuridega loetakse kehtivaks. Valideerimine hõlmab sisu rangeks täpsustamiseks lihtsalt andmetüüpe ja loendeid.
  • Räsifunktsioon sharding - Kafka sõnumi struktuur on võtmeväärtus ja võtme räsi abil arvutatakse, kuhu see paigutada.

Miks

Töötame suures, sujuva protsessiga ettevõttes. Miks midagi muuta? See on eksperimentja loodame saada mitmeid eeliseid.

1:n+1 vahetust (üks mitmele)

Kafka teeb uute tarbijate ühendamise API-ga väga lihtsaks.

Oletame, et teil on kataloog, mida peate korraga mitmes süsteemis (ja mõnes uues) ajakohasena hoidma. Varem leiutasime komplekti, mis rakendas set-API-d ja põhisüsteemi teavitati tarbijate aadressidest. Nüüd saadab põhisüsteem teemale uuendusi ja kõik huvilised loevad seda. Ilmunud on uus süsteem – panime selle teemasse kirja. Jah, ka kimp, aga lihtsam.

Tagastustööriista puhul, mis on TP tükk, on meil mugav hoida neid Kafka kaudu sünkroonituna. Makse ütleb, et raha tagastati: BOB, RT sai sellest teada, muutis oma staatusi, Fiscalization Service sai sellest teada ja väljastas tšeki.

Kogemused Kafka asünkroonse API-ga tagastustööriista teenuse arendamisel

Meil on plaanis luua ühtne teavitusteenus, mis teavitaks klienti tema tellimuse/tagastamisega seotud uudistest. Nüüd on see vastutus süsteemide vahel jaotatud. Piisab, kui õpetame teavitusteenust Kafkalt asjakohast teavet püüdma ja sellele vastama (ja teistes süsteemides need teatised keelama). Uusi otsevahetusi pole vaja.

Andmepõhine

Süsteemidevaheline teave muutub läbipaistvaks – olenemata sellest, milline "verine ettevõte" teil on ja kui suur on teie mahajäämus. Lamodal on andmeanalüüsi osakond, mis kogub süsteemidest andmeid ja paneb need taaskasutatavasse vormi nii äri kui ka intelligentsete süsteemide jaoks. Kafka võimaldab teil kiiresti anda neile palju andmeid ja hoida seda teabevoogu ajakohasena.

Replikatsiooni logi

Sõnumid ei kao pärast lugemist, nagu RabbitMQ puhul. Kui sündmus sisaldab töötlemiseks piisavalt teavet, on meil objekti hiljutiste muudatuste ajalugu ja soovi korral võimalus neid muudatusi rakendada.

Replikatsioonilogi salvestusperiood sõltub sellesse teemasse kirjutamise intensiivsusest, Kafka võimaldab paindlikult seada piiranguid salvestusajale ja andmemahule. Intensiivsete teemade puhul on oluline, et kõigil tarbijatel oleks ka lühiajalise töövõimetuse korral aega infoga tutvuda enne selle kadumist. Tavaliselt on võimalik andmeid salvestada päevade ühikud, mis on toetuseks täiesti piisav.

Kogemused Kafka asünkroonse API-ga tagastustööriista teenuse arendamisel

Järgmiseks väike ümberjutustus dokumentatsioonist, neile, kes Kafkaga kursis pole (pilt on samuti dokumentatsioonist)

AMQP-l on järjekorrad: me kirjutame tarbija jaoks järjekorda sõnumid. Tavaliselt töötleb ühte järjekorda üks süsteem sama äriloogikaga. Kui teil on vaja teavitada mitut süsteemi, saate õpetada rakendust kirjutama mitmesse järjekorda või konfigureerida vahetust fanout-mehhanismiga, mis need ise kloonib.

Kafkal on sarnane abstraktsioon teema, millesse kirjutate sõnumeid, kuid need ei kao pärast lugemist. Vaikimisi saate Kafkaga ühenduse loomisel kõik sõnumid ja teil on võimalus salvestada kohta, kus pooleli jäite. See tähendab, et loete järjest, te ei tohi sõnumit loetuks märkida, vaid salvestate ID, kust saate lugemist jätkata. ID-d, mille arveldasite, nimetatakse nihkeks ja mehhanismi nihkeks.

Sellest lähtuvalt saab rakendada erinevat loogikat. Näiteks on meil TP 4 erineva riigi puhul – Lamoda on Venemaal, Kasahstanis, Ukrainas, Valgevenes. Kuna neid juurutatakse eraldi, on neil veidi erinevad konfiguratsioonid ja oma äriloogika. Teatame sõnumis, millisele riigile see viitab. Iga TP tarbija igas riigis loeb erineva groupId-ga ja kui sõnum tema kohta ei kehti, jätab ta selle vahele, s.t. teeb kohe nihke +1. Kui sama teemat loeb meie Makseteenus, siis teeb ta seda eraldi grupiga ja seetõttu nihked ei ristu.

Ürituse nõuded:

  • Andmete täielikkus. Soovin, et sündmusel oleks piisavalt andmeid, et seda saaks töödelda.

  • Terviklikkus Delegeerime Events-busile kontrolli, kas sündmus on järjepidev ja suudab seda töödelda.
  • Järjekord on oluline. Tagasituleku puhul oleme sunnitud töötama ajalooga. Teadete puhul ei ole tellimus oluline, kui tegemist on homogeensete teadetega, on meil sama, olenemata sellest, milline tellimus saabus esimesena. Tagastamise puhul on protsess selge, kui muudame tellimust, tekivad erandid, tagasimakset ei koostata ega töödelda – jõuame teise staatusesse.
  • Järjepidevus. Meil on pood ja nüüd loome API asemel sündmusi. Vajame võimalust kiiresti ja odavalt oma teenustesse edastada infot uute sündmuste ja olemasolevate muudatuste kohta. See saavutatakse ühise spetsifikatsiooni kaudu eraldi git-hoidlas ja koodigeneraatorites. Seetõttu on erinevates teenustes kliendid ja serverid kooskõlastatud.

Kafka Lamodas

Meil on kolm Kafka installatsiooni:

  1. Palgid;
  2. R&D;
  3. Üritused-buss.

Täna räägime ainult viimasest punktist. Ürituste-bussides meil väga suuri installatsioone ei ole - 3 maaklerit (serverit) ja ainult 27 teemat. Reeglina on üks teema üks protsess. Kuid see on peen punkt ja me käsitleme seda nüüd.

Kogemused Kafka asünkroonse API-ga tagastustööriista teenuse arendamisel

Ülal on rps graafik. Tagasimakseprotsess on tähistatud türkiissinise joonega (jah, see, mis asub X-teljel) ja roosa joon on sisu värskendamise protsess.

Lamoda kataloog sisaldab miljoneid tooteid ja andmeid uuendatakse kogu aeg. Mõned kollektsioonid lähevad moest välja, asemele lastakse välja uued ning kataloogi ilmuvad pidevalt uued mudelid. Püüame ennustada, mis meie klientidele homme huvi pakub, seega ostame pidevalt uusi asju, pildistame neid ja uuendame vitriine.

Roosad tipud on tooteuuendused, st muudatused toodetes. On näha, et tüübid tegid pilte, tegid pilte ja siis jälle! — laadis paki üritusi.

Lamoda Eventsi kasutusjuhtumid

Konstrueeritud arhitektuuri kasutame järgmiste toimingute jaoks:

  • Tagastamise oleku jälgimine: kutse tegevusele ja oleku jälgimine kõigist kaasatud süsteemidest. Makse, olekud, fiskaliseerimine, teatised. Siin katsetasime lähenemist, tegime tööriistu, kogusime kokku kõik vead, kirjutasime dokumentatsiooni ja rääkisime kolleegidele, kuidas seda kasutada.
  • Tootekaartide värskendamine: konfiguratsioon, metaandmed, omadused. Üks süsteem loeb (mis kuvab) ja mitu kirjutab.
  • Meil, push ja sms: tellimus on kogutud, tellimus saabunud, tagastus vastu võetud jne, neid on palju.
  • Laoseisu, lao uuendamine — kaupade kvantitatiivne ajakohastamine, ainult numbrid: lattu saabumine, tagastamine. Kõik kaupade broneerimisega seotud süsteemid peavad töötama kõige värskemate andmetega. Praegu on varude uuendamise süsteem üsna keeruline, Kafka lihtsustab seda.
  • Andmete analüüs (R&D osakond), ML tööriistad, analüütika, statistika. Soovime, et teave oleks läbipaistev – Kafka sobib selleks hästi.

Nüüd huvitavam osa suurtest konarustest ja huvitavatest avastustest, mis viimase poole aasta jooksul on toimunud.

Disaini probleemid

Oletame, et tahame teha uut asja – näiteks viia kogu tarneprotsess üle Kafkale. Nüüd on osa protsessist rakendatud tellimuste töötlemisel TP-s. Tellimuse tarneteenusele üleandmise, vahelattu liikumise jms taga on staatusmudel. Seal on terve monoliit, isegi kaks, pluss hunnik kohaletoimetamiseks mõeldud API-sid. Nad teavad kohaletoimetamisest palju rohkem.

Need tunduvad olevat sarnased valdkonnad, kuid tellimuste töötlemisel TP-s ja saatmissüsteemil on erinevad olekud. Näiteks mõned kullerteenused ei saada vahepealseid staatusi, vaid ainult lõplikke olekuid: “tarnitud” või “kadunud”. Teised, vastupidi, teatavad kaupade liikumisest väga üksikasjalikult. Kõigil on oma valideerimisreeglid: mõne jaoks on meil kehtiv, mis tähendab, et seda töödeldakse; teistel see ei kehti, aga tellimus läheb siiski vormistamisele, sest kontakti saamiseks on telefoninumber olemas ja keegi ütleb, et sellist tellimust üldse ei vormistata.

Andmevoog

Kafka puhul kerkib küsimus andmevoo korraldamisest. See ülesanne hõlmab mitme punkti põhjal strateegia valimist; vaatame need kõik läbi.

Ühes teemas või erinevates?

Meil on sündmuse spetsifikatsioon. TP-sse kirjutame, et selline ja selline tellimus tuleb kohale toimetada, ja märgime: tellimuse number, selle koostis, mõned SKU-d ja triipkoodid jne. Kauba lattu saabumisel saab tarne saada staatused, ajatemplid ja kõik vajaliku. Kuid siis tahame saada värskendusi nende andmete kohta TP-s. Meil on tarneandmete vastuvõtmise protsess vastupidine. Kas see on sama sündmus? Või on see eraldi vahetus, mis väärib oma teemat?

Tõenäoliselt on need väga sarnased ja kiusatus teha üks teema pole alusetu, sest eraldi teema tähendab eraldi tarbijaid, eraldi konfiguratsioone, kõige selle eraldi genereerimist. Aga mitte fakt.

Uus valdkond või uus üritus?

Kui aga kasutada samu sündmusi, tekib teine ​​probleem. Näiteks mitte kõik edastussüsteemid ei suuda genereerida sellist DTO-d, mida BOB suudab genereerida. Saadame neile ID, kuid nad ei salvesta seda, kuna neil pole seda vaja, ja sündmuse-bussi protsessi käivitamise seisukohalt on see väli kohustuslik.

Kui kehtestame sündmuste siini jaoks reegli, et see väli on kohustuslik, oleme sunnitud TP-s või stardisündmuse käitlejas määrama täiendavaid valideerimisreegleid. Valideerimine hakkab levima kogu teenuses - see pole eriti mugav.

Teine probleem on kiusatus järkjärguliseks arenguks. Meile öeldakse, et üritusele tuleb midagi lisada ja võib-olla, kui järele mõelda, oleks see pidanud olema eraldi üritus. Aga meie skeemis on eraldi üritus omaette teema. Eraldi teema on kogu protsess, mida ma eespool kirjeldasin. Arendajal on kiusatus JSON-skeemile lihtsalt lisada veel üks väli ja see uuesti luua.

Tagasimaksete puhul jõudsime üritusele poole aastaga. Meil oli üks metasündmus nimega tagasimakse värskendus, millel oli tüübiväli, mis kirjeldas, mida see värskendus tegelikult endast kujutab. Seetõttu olid meil "imelised" lülitid koos validaatoritega, kes rääkisid meile, kuidas seda sündmust seda tüüpi abil kinnitada.

Sündmuse versioonimine

Sõnumite kinnitamiseks Kafkas saate kasutada Avro, kuid oli vaja kohe peale visata ja Confluenti kasutada. Meie puhul peame olema versioonide loomisega ettevaatlikud. Alati ei ole võimalik replikatsioonilogist sõnumeid uuesti lugeda, kuna mudel on "lahkunud". Põhimõtteliselt tuleb välja, et ehitada versioone nii, et mudel on tagurpidi ühilduv: näiteks muuta väli ajutiselt valikuliseks. Kui erinevused on liiga suured, hakkame kirjutama uues teemas ja kliendid edastame, kui nad vana teema lugemise lõpetavad.

Garanteeritud vaheseinte lugemisjärjekord

Kafka sees olevad teemad on jagatud vaheseinteks. See ei ole üksuste ja börside kavandamisel kuigi oluline, kuid see on oluline, kui otsustate, kuidas seda tarbida ja skaleerida.

Tavalisel juhul kirjutad ühe teema Kafkas. Vaikimisi kasutatakse ühte partitsiooni ja kõik selle teema kirjad lähevad sellele. Järelikult loeb tarbija neid sõnumeid järjest. Oletame, et nüüd tuleb süsteemi laiendada nii, et sõnumeid loevad kaks erinevat tarbijat. Kui saadate näiteks SMS-i, võite öelda, et Kafka teeks täiendava partitsiooni ja Kafka hakkab sõnumeid jagama kaheks osaks - pooled siia, pooled siia.

Kuidas Kafka neid jagab? Igal sõnumil on keha (millesse salvestame JSON-i) ja võti. Sellele võtmele saate lisada räsifunktsiooni, mis määrab, millisesse partitsiooni sõnum läheb.

Meie puhul on tagasimaksete puhul see oluline, kui võtame kaks partitsiooni, siis on võimalus, et paralleeltarbija töötleb teise sündmuse enne esimest ja tekib tõrge. Räsifunktsioon tagab, et sama võtmega sõnumid jõuavad samasse partitsiooni.

Sündmused vs käsud

See on veel üks probleem, millega me kokku puutusime. Sündmus on kindel sündmus: me ütleme, et kuskil juhtus midagi (midagi_juhtus), näiteks kaup tühistati või raha tagastati. Kui keegi kuulab neid sündmusi, siis vastavalt "üks tühistatud" luuakse tagasimakse olem ja kuhugi seadistustesse kirjutatakse "tagasimakse toimus".

Kuid tavaliselt ei taha te üritusi kavandades neid ilmaasjata kirjutada – tuginete sellele, et keegi neid loeb. On suur kiusatus kirjutada mitte midagi_juhtunud (üks_tühistatud, tagasimakstud_raha), vaid midagi_peaks_teha. Näiteks kaup on tagastamiseks valmis.

Ühest küljest annab see mõista, kuidas üritust kasutatakse. Teisest küljest kõlab see palju vähem tavalise sündmuse nimena. Pealegi pole siit kaugel käsk do_something. Kuid teil pole mingit garantiid, et keegi seda sündmust loeb; ja kui loed, siis loed edukalt; ja kui sa lugesid seda edukalt, siis sa tegid midagi ja see miski õnnestus. Kui sündmus muutub midagi tegema, muutub tagasiside vajalikuks ja see on probleem.

Kogemused Kafka asünkroonse API-ga tagastustööriista teenuse arendamisel

RabbitMQ asünkroonses vahetuses minge sõnumi lugemisel aadressile http, teil on vastus - vähemalt see, et sõnum võeti vastu. Kui kirjutate Kafkale, on sõnum, mille kirjutasite Kafkale, kuid te ei tea midagi selle töötlemisest.

Seetõttu pidime meie puhul sisse viima reageerimissündmuse ja seadistama monitooringu, et kui nii palju sündmusi saadeti, siis sellise ja sellise aja peale peaks saabuma sama palju reageerimissündmusi. Kui seda ei juhtu, tundub, et midagi on valesti läinud. Näiteks kui saatsime sündmuse "artikkel_ready_to_refund", eeldame, et luuakse raha tagasimakse, raha tagastatakse kliendile ja sündmus "raha_tagastatud" saadetakse meile. Kuid see pole kindel, seega on vaja jälgida.

Nüansid

On üsna ilmne probleem: kui loed teemast järjestikku ja sul on mõni halb sõnum, langeb tarbija ja sa ei jõua kaugemale. Sa vajad peatada kõik tarbijad, määrake lugemise jätkamiseks nihe veelgi.

Teadsime sellest, arvestasime sellega ja ometi see juhtus. Ja see juhtus seetõttu, et sündmus kehtis sündmuste-bussi seisukohalt, sündmus kehtis rakenduste validaatori seisukohalt, kuid see ei kehtinud PostgreSQL-i seisukohalt, sest meie ühes süsteemis MySQL koos UNISIGNED INT-ga ja äsja kirjutatud süsteemis oli PostgreSQL ainult INT-ga. Tema suurus on veidi väiksem ja Id ei sobinud. Symfony suri erandiga. Muidugi tabasime erandit, kuna tuginesime sellele ja kavatsesime selle nihke teha, kuid enne seda tahtsime probleemiloendurit suurendada, kuna sõnumi töötlemine ebaõnnestus. Selle projekti loendurid on samuti andmebaasis ja Symfony on juba sulgenud side andmebaasiga ning teine ​​erand tappis kogu protsessi ilma nihke tegemise võimaluseta.

Teenindus jäi mõnda aega pikali - õnneks pole see Kafka puhul nii hull, sest sõnumid jäävad alles. Kui töö on taastatud, saate nende lugemise lõpetada. See on mugav.

Kafkal on tööriistade abil võimalik seada meelevaldne nihe. Kuid selleks peate peatama kõik tarbijad - meie puhul valmistage ette eraldi väljaanne, milles tarbijaid, ümberpaigutamist ei toimu. Seejärel saate Kafkas nihket tööriistade abil nihutada ja sõnum edastatakse.

Veel üks nüanss - replikatsioonilogi vs rdkafka.so - on seotud meie projekti spetsiifikaga. Me kasutame PHP-d ja PHP-s suhtlevad kõik teegid Kafkaga reeglina rdkafka.so hoidla kaudu ja siis on mingi ümbris. Võib-olla on need meie isiklikud raskused, kuid selgus, et lihtsalt juba loetu uuesti lugemine polegi nii lihtne. Üldiselt oli tarkvaraprobleeme.

Tulles tagasi vaheseintega töötamise spetsiifika juurde, on see dokumentatsioonis otse kirjas tarbijad >= teemajaotised. Kuid sain sellest teada palju hiljem, kui oleksin soovinud. Kui soovite skaleerida ja teil on kaks tarbijat, on teil vaja vähemalt kahte partitsiooni. See tähendab, et kui teil oli üks partitsioon, kuhu oli kogunenud 20 tuhat sõnumit, ja tegite uue, siis sõnumite arvu niipea ei ühtlusta. Seetõttu peate kahe paralleelse tarbija jaoks tegelema vaheseintega.

Jälgimine

Arvan, et see, kuidas me seda jälgime, saab veelgi selgemaks, millised probleemid on olemasolevas lähenemisviisis.

Näiteks arvutame välja, kui palju andmebaasis olevaid tooteid on hiljuti oma olekut muutnud ja vastavalt sellele oleks pidanud nende muudatuste põhjal sündmused toimuma ning saadame selle numbri meie seiresüsteemi. Siis saame Kafkalt teise numbri, mitu sündmust tegelikult salvestati. Ilmselgelt peaks nende kahe numbri vahe olema alati null.

Kogemused Kafka asünkroonse API-ga tagastustööriista teenuse arendamisel

Lisaks tuleb jälgida, kuidas läheb tootjal, kas sündmused-buss said teateid ja kuidas läheb tarbijal. Näiteks allolevates diagrammides läheb tagasimakse tööriistal hästi, kuid TP-l on selgelt probleeme (sinised tipud).

Kogemused Kafka asünkroonse API-ga tagastustööriista teenuse arendamisel

Ma juba mainisin tarbijagrupi mahajäämust. Jämedalt öeldes on see lugemata sõnumite arv. Üldiselt töötavad meie tarbijad kiiresti, nii et viivitus on tavaliselt 0, kuid mõnikord võib esineda lühiajaline tipp. Kafka saab seda teha karbist väljas, kuid peate määrama teatud intervalli.

Projekt on olemas urgmis annab teile Kafka kohta rohkem teavet. See kasutab lihtsalt tarbijarühma API-t, et anda oleku kohta, kuidas sellel rühmal läheb. Lisaks OK ja Failed on hoiatus ning saate teada, et teie tarbijad ei tule tootmistempoga toime – neil pole aega kirjutatu korrektuuriks. Süsteem on üsna nutikas ja hõlpsasti kasutatav.

Kogemused Kafka asünkroonse API-ga tagastustööriista teenuse arendamisel

API vastus näeb välja selline. Siin on grupp bob-live-fifa, partitsioon refund.update.v1, olek OK, lag 0 – viimane lõppnihe selline ja selline.

Kogemused Kafka asünkroonse API-ga tagastustööriista teenuse arendamisel

Jälgimine updated_at SLA (kinni) Ma juba mainisin. Näiteks on toode muutunud olekusse, et see on tagastamiseks valmis. Paigaldame Croni, mis ütleb, et kui 5 minutiga pole see objekt läinud tagasimaksmisele (tagastame raha väga kiiresti läbi maksesüsteemide), siis läks kindlasti midagi valesti ja see on kindlasti toe juhtum. Seetõttu võtame lihtsalt Croni, mis selliseid asju loeb ja kui need on suuremad kui 0, saadab see hoiatuse.

Kokkuvõtteks võib öelda, et sündmuste kasutamine on mugav, kui:

  • teavet vajavad mitmed süsteemid;
  • töötlemise tulemus pole oluline;
  • üritusi või väikseid üritusi on vähe.

Tundub, et artiklil on väga konkreetne teema - asünkroonne API Kafkas, kuid sellega seoses tahaksin soovitada palju asju korraga.
Esiteks, järgmine HighLoad ++ peame ootama novembrini, aprillis tuleb Peterburi versioon ja juunis räägime Novosibirski suurtest koormustest.
Teiseks on raporti autor Sergei Zaika meie uue teadmusjuhtimise konverentsi programmikomitee liige. KnowledgeConf. Konverents on ühepäevane, toimub 26. aprillil, kuid selle programm on väga tihe.
Ja see saab olema mais PHP Venemaa и RIT++ (koos DevOpsConfiga) - seal saab ka oma teemat soovitada, oma kogemustest rääkida ja oma topitud käbide üle kurta.

Allikas: www.habr.com

Lisa kommentaar