Pieredze pakalpojuma Refund Tool izstrādē ar asinhrono API vietnē Kafka

Kas varētu likt tik lielam uzņēmumam kā Lamoda ar racionalizētu procesu un desmitiem savstarpēji saistÄ«tu pakalpojumu bÅ«tiski mainÄ«t savu pieeju? Motivācija var bÅ«t pilnÄ«gi atŔķirÄ«ga: no likumdoÅ”anas lÄ«dz vēlmei eksperimentēt, kas raksturÄ«ga visiem programmētājiem.

Bet tas nenozÄ«mē, ka jÅ«s nevarat rēķināties ar papildu priekÅ”rocÄ«bām. Sergejs Zaika pastāstÄ«s, ko tieÅ”i jÅ«s varat laimēt, ievieÅ”ot uz notikumiem orientētu API vietnē Kafka (mazalds). Noteikti tiks runāts arÄ« par lieliem kadriem un interesantiem atklājumiem ā€“ bez tiem eksperiments neiztikt.

Pieredze pakalpojuma Refund Tool izstrādē ar asinhrono API vietnē Kafka

Atruna: Ŕī raksta pamatā ir materiāli no tikÅ”anās, ko Sergejs rÄ«koja 2018. gada novembrÄ« vietnē HighLoad++. Lamoda tieÅ”raides pieredze darbā ar Kafku piesaistÄ«ja klausÄ«tājus ne mazāk kā citi ziņojumi par grafiku. MÅ«suprāt, Å”is ir lielisks piemērs tam, ka vienmēr var un vajag atrast domubiedrus, un HighLoad++ organizatori arÄ« turpmāk centÄ«sies radÄ«t tam labvēlÄ«gu atmosfēru.

Par procesu

Lamoda ir liela e-komercijas platforma, kurai ir savs kontaktu centrs, piegādes pakalpojums (un daudzi saistÄ«tie uzņēmumi), fotostudija, milzÄ«ga noliktava, un tas viss darbojas, izmantojot savu programmatÅ«ru. Ir vairāki desmiti maksājumu metožu, B2B partneri, kuri var izmantot dažus vai visus no Å”iem pakalpojumiem un vēlas uzzināt jaunāko informāciju par saviem produktiem. Turklāt Lamoda darbojas trÄ«s valstÄ«s bez Krievijas Federācijas un tur viss ir nedaudz savādāk. Kopumā, iespējams, ir vairāk nekā simts veidu, kā konfigurēt jaunu pasÅ«tÄ«jumu, kas ir jāapstrādā savā veidā. Tas viss darbojas, izmantojot desmitiem pakalpojumu, kas dažreiz sazinās nepārprotamā veidā. Ir arÄ« centrālā sistēma, kuras galvenā atbildÄ«ba ir pasÅ«tÄ«jumu statusi. Mēs viņu saucam par BOB, es strādāju ar viņu.

Atmaksas rīks ar uz notikumiem balstītu API

Vārds notikumu virzÄ«ts ir diezgan izlaists; nedaudz tālāk mēs sÄ«kāk definēsim, kas ar to tiek domāts. SākÅ”u ar kontekstu, kurā mēs nolēmām izmēģināt uz notikumiem balstÄ«to API pieeju Kafkā.

Pieredze pakalpojuma Refund Tool izstrādē ar asinhrono API vietnē Kafka

Jebkurā veikalā papildus pasÅ«tÄ«jumiem, par kuriem klienti maksā, ir reizes, kad veikalam tiek prasÄ«ts atdot naudu, jo prece klientam nav bijusi piemērota. Tas ir salÄ«dzinoÅ”i Ä«ss process: nepiecieÅ”amÄ«bas gadÄ«jumā precizējam informāciju un pārskaitām naudu.

Bet atdoÅ”ana kļuva sarežģītāka sakarā ar izmaiņām likumdoÅ”anā, un mums nācās tai ieviest atseviŔķu mikropakalpojumu.

Pieredze pakalpojuma Refund Tool izstrādē ar asinhrono API vietnē Kafka

Mūsu motivācija:

  1. Likums FZ-54 - Ä«si sakot, likums nosaka, ka par katru naudas darÄ«jumu, neatkarÄ«gi no tā, vai tā ir atgrieÅ”ana vai kvÄ«ts, ir jāziņo nodokļu inspekcijai diezgan Ä«sā SLA ā€“ dažu minÅ«Å”u laikā. Mēs kā e-komercijas uzņēmums veicam diezgan daudz operāciju. Tehniski tas nozÄ«mē jaunu atbildÄ«bu (un lÄ«dz ar to jaunu pakalpojumu) un uzlabojumus visās iesaistÄ«tajās sistēmās.
  2. BOB sadalÄ«jums ir uzņēmuma iekŔējais projekts, lai atbrÄ«votu BOB no daudziem nesaistÄ«tiem pienākumiem un samazinātu tā vispārējo sarežģītÄ«bu.

Pieredze pakalpojuma Refund Tool izstrādē ar asinhrono API vietnē Kafka

Å Ä« diagramma parāda galvenās Lamoda sistēmas. Tagad lielākā daļa no tiem ir vairāk 5-10 mikropakalpojumu konstelācija ap sarÅ«koÅ”u monolÄ«tu. Tie lēnām aug, bet cenÅ”amies tos padarÄ«t mazākus, jo vidÅ« izvēlētā fragmenta izvietoÅ”ana ir biedējoÅ”a - nevaram ļaut tam nokrist. Mēs esam spiesti rezervēt visas maiņas (bultiņas) un ņemt vērā to, ka kāda no tām var izrādÄ«ties nepieejama.

BOB ir arī diezgan daudz biržu: maksājumu sistēmas, piegādes sistēmas, paziņojumu sistēmas utt.

Tehniski BOB ir:

  • ~150k koda rindiņu + ~100k rindiņu testu;
  • php7.2 + Zend 1 un Symfony Components 3;
  • >100 API un ~50 izejoŔās integrācijas;
  • 4 valstis ar savu biznesa loÄ£iku.

BOB izvietoÅ”ana ir dārga un sāpÄ«ga, koda un atrisināmo problēmu daudzums ir tāds, ka neviens to visu nevar ielikt savā galvā. Kopumā ir daudz iemeslu, lai to vienkārÅ”otu.

AtgrieŔanas process

Sākotnēji procesā ir iesaistītas divas sistēmas: BOB un Payment. Tagad parādās vēl divi:

  • Fiskalizācijas dienests, kas parÅ«pēsies par problēmām ar fiskalizāciju un saziņu ar ārējiem dienestiem.
  • Atmaksas rÄ«ks, kas vienkārÅ”i satur jaunas maiņas, lai nepalielinātu BOB.

Tagad process izskatās Ŕādi:

Pieredze pakalpojuma Refund Tool izstrādē ar asinhrono API vietnē Kafka

  1. BOB saņem atmaksas pieprasījumu.
  2. BOB stāsta par Ŕo atmaksas rīku.
  3. Atmaksas rÄ«ks parāda maksājumam: ā€œAtdod nauduā€.
  4. Maksājums atdod naudu.
  5. Atmaksas rÄ«ks un BOB sinhronizē statusus viens ar otru, jo pagaidām abiem tas ir nepiecieÅ”ams. Mēs vēl neesam gatavi pilnÄ«bā pāriet uz atmaksas rÄ«ku, jo BOB ir lietotāja saskarne, atskaites grāmatvedÄ«bai un kopumā daudz datu, kurus nevar tik vienkārÅ”i pārsÅ«tÄ«t. Jums jāsēž uz diviem krēsliem.
  6. Fiskalizācijas pieprasījums pazūd.

Rezultātā uz Kafkas uztaisījām tādu kā pasākumu autobusu - pasākums-buss, uz kura viss sākās. Urā, tagad mums ir viens neveiksmes punkts (sarkasms).

Pieredze pakalpojuma Refund Tool izstrādē ar asinhrono API vietnē Kafka

Plusi un mÄ«nusi ir diezgan acÄ«mredzami. Mēs uztaisÄ«jām autobusu, kas nozÄ«mē, ka tagad no tā ir atkarÄ«gi visi pakalpojumi. Tas vienkārÅ”o dizainu, bet sistēmā ievieÅ” vienu atteices punktu. Kafka sabruks, process apstāsies.

Kas ir uz notikumiem orientēta API

Laba atbilde uz Å”o jautājumu ir Martina Faulera ziņojumā (GOTO 2017) "Daudzās notikumu vadÄ«tas arhitektÅ«ras nozÄ«mes".

ÄŖsumā, ko mēs darÄ«jām:

  1. Aptiniet visas asinhronās apmaiņas, izmantojot notikumu krātuve. Tā vietā, lai informētu katru ieinteresēto patērētāju par statusa maiņu tÄ«klā, mēs rakstām notikumu par statusa maiņu centralizētajā krātuvē, un patērētāji, kurus interesē Ŕī tēma, lasa visu, kas no turienes parādās.
  2. Å ajā gadÄ«jumā notikums ir paziņojums (paziņojumi), ka kaut kas ir mainÄ«jies. Piemēram, ir mainÄ«jies pasÅ«tÄ«juma statuss. Patērētājs, kuru interesē daži statusa maiņu pavadoÅ”ie dati, kas nav iekļauti paziņojumā, to statusu var uzzināt pats.
  3. Maksimālā iespēja ir pilnvērtÄ«ga pasākumu piegāde, valsts nodoÅ”ana, kurā notikumā ir visa apstrādei nepiecieÅ”amā informācija: no kurienes tā nākusi un kādā statusā tā nonākusi, kā tieÅ”i dati mainÄ«juÅ”ies utt. Jautājums ir tikai par iespējamÄ«bu un informācijas apjomu, ko varat atļauties uzglabāt.

Atmaksas rÄ«ka palaiÅ”anas ietvaros mēs izmantojām treÅ”o iespēju. Å Ä« vienkārÅ”ota notikumu apstrāde, jo nebija nepiecieÅ”amÄ«bas iegÅ«t detalizētu informāciju, kā arÄ« tika novērsts scenārijs, kad katrs jauns notikums rada precizējoÅ”us pieprasÄ«jumus no patērētājiem.

Atmaksas rÄ«ku pakalpojums nav ielādēts, tāpēc Kafka ir vairāk pildspalvas garÅ”a nekā nepiecieÅ”amÄ«ba. Es nedomāju, ka, ja atmaksas pakalpojums kļūtu par augstas slodzes projektu, bizness bÅ«tu laimÄ«gs.

Asinhronā apmaiņa TĀDA, KĀ IR

Asinhronai apmaiņai PHP nodaļa parasti izmanto RabbitMQ. Mēs apkopojām pieprasÄ«juma datus, ievietojām tos rindā, un tā paÅ”a pakalpojuma patērētājs tos izlasÄ«ja un nosÅ«tÄ«ja (vai nenosÅ«tÄ«ja). PaÅ”ai API Lamoda aktÄ«vi izmanto Swagger. Mēs izstrādājam API, aprakstām to programmā Swagger un Ä£enerējam klienta un servera kodu. Mēs izmantojam arÄ« nedaudz uzlabotu JSON RPC 2.0.

Dažās vietās tiek izmantoti ESB autobusi, daži dzīvo uz activeMQ, bet kopumā RabbitMQ - standarta.

Asinhronā apmaiņa TO BE

Projektējot apmaiņu, izmantojot notikumu autobusu, var izsekot lÄ«dzÄ«bai. Mēs lÄ«dzÄ«gi aprakstām turpmāko datu apmaiņu, izmantojot notikumu struktÅ«ras aprakstus. Yaml formāts, mums paÅ”iem bija jāveic koda Ä£enerÄ“Å”ana, Ä£enerators izveido DTO pēc specifikācijas un iemāca ar tiem strādāt klientiem un serveriem. Paaudze pāriet divās valodās - golang un php. Tas palÄ«dz nodroÅ”ināt bibliotēku konsekvenci. Ä¢enerators ir rakstÄ«ts golangā, tāpēc tas ieguva nosaukumu gogi.

Pasākumu iegÅ«Å”ana vietnē Kafka ir tipiska lieta. Ir risinājums no Kafka Confluent galvenās uzņēmuma versijas nakadi, risinājums no mÅ«su domēna brāļiem Zalando. MÅ«su motivācija sākt ar vaniļas Kafku - tas nozÄ«mē atstāt risinājumu brÄ«vi, lÄ«dz beidzot izlemsim, vai to izmantosim visur, kā arÄ« atstāt sev manevra un uzlabojumu iespējas: mēs vēlamies atbalstu mÅ«su JSON RPC 2.0, Ä£eneratori divām valodām un redzēsim, kas vēl.

Ironiski, ka pat tik laimīgā gadījumā, kad ir aptuveni līdzīgs bizness Zalando, kas radīja aptuveni līdzīgu risinājumu, mēs nevaram to izmantot efektīvi.

ArhitektÅ«ras modelis palaiÅ”anas brÄ«dÄ« ir Ŕāds: mēs lasām tieÅ”i no Kafkas, bet rakstām tikai caur notikumu autobusu. Kafkā daudz kas ir gatavs lasÄ«Å”anai: brokeri, balansieri, un tas ir vairāk vai mazāk gatavs horizontālai mērogoÅ”anai, es gribēju to paturēt. Mēs vēlējāmies pabeigt ierakstu, izmantojot vienu Gateway jeb Events-bus, un lÅ«k, kāpēc.

Pasākumi-autobuss

Vai pasākumu autobuss. Šī ir vienkārŔi bezvalstnieka http vārteja, kurai ir vairākas svarīgas lomas:

  • Validācijas izgatavoÅ”ana ā€” mēs pārbaudām, vai pasākumi atbilst mÅ«su specifikācijām.
  • Pasākumu meistarsistēma, proti, Ŕī ir galvenā un vienÄ«gā sistēma uzņēmumā, kas atbild uz jautājumu, kādi notikumi ar kādām struktÅ«rām tiek uzskatÄ«ti par derÄ«giem. Validācija vienkārÅ”i ietver datu tipus un uzskaitÄ«jumus, lai stingri norādÄ«tu saturu.
  • Hash funkcija sadalÄ«Å”anai - Kafka ziņojuma struktÅ«ra ir atslēgas vērtÄ«ba, un, izmantojot atslēgas jaucējkodu, tiek aprēķināts, kur to ievietot.

Kāpēc

Mēs strādājam lielā uzņēmumā ar racionalizētu procesu. Kāpēc kaut ko mainÄ«t? Å is ir eksperiments, un mēs ceram gÅ«t vairākas priekÅ”rocÄ«bas.

1:n+1 apmaiņas (no viena līdz daudzām)

Kafka ļauj ļoti vienkārÅ”i savienot jaunus patērētājus ar API.

Pieņemsim, ka jums ir direktorijs, kas ir jāatjaunina vairākās sistēmās vienlaikus (un dažās jaunās). IepriekÅ” mēs izgudrojām komplektu, kas ieviesa set-API, un galvenā sistēma tika informēta par patērētāju adresēm. Tagad galvenā sistēma nosÅ«ta tēmas atjauninājumus, un visi interesenti to izlasa. Ir parādÄ«jusies jauna sistēma - pierakstÄ«jāmies par tēmu. Jā, arÄ« komplektā, bet vienkārŔāk.

Atmaksas rīka gadījumā, kas ir BOB gabals, mums ir ērti tos sinhronizēt, izmantojot Kafka. Maksājumā teikts, ka nauda tika atgriezta: BOB, RT par to uzzināja, mainīja statusus, Fiskalizācijas dienests to uzzināja un izsniedza čeku.

Pieredze pakalpojuma Refund Tool izstrādē ar asinhrono API vietnē Kafka

Esam plānojuÅ”i izveidot vienotu Paziņojumu servisu, kas informētu klientu par jaunumiem saistÄ«bā ar viņa pasÅ«tÄ«jumu/atgrieÅ”anu. Tagad Ŕī atbildÄ«ba ir sadalÄ«ta starp sistēmām. Pietiks, ja mēs iemācÄ«sim Paziņojumu dienestam noÄ·ert no Kafkas bÅ«tisku informāciju un uz to reaģēt (un atspējot Å”os paziņojumus citās sistēmās). Jaunas tieŔās apmaiņas nebÅ«s vajadzÄ«gas.

Datu vadīts

Informācija starp sistēmām kļūst caurspÄ«dÄ«ga ā€” neatkarÄ«gi no tā, kāds jums ir "asiņains uzņēmums", un neatkarÄ«gi no tā, cik liels ir jÅ«su neatmaksātais apjoms. Lamoda ir Datu analÄ«zes nodaļa, kas apkopo datus no sistēmām un ievieto tos atkārtoti lietojamā formā gan biznesam, gan viedajām sistēmām. Kafka ļauj ātri sniegt viņiem daudz datu un atjaunināt Å”o informācijas plÅ«smu.

Replikācijas žurnāls

Ziņojumi pēc lasÄ«Å”anas nepazÅ«d, kā tas ir RabbitMQ. Ja notikums satur pietiekami daudz informācijas apstrādei, mums ir nesen veikto izmaiņu vēsture objektā un, ja vēlaties, iespēja piemērot Ŕīs izmaiņas.

Replikācijas žurnāla glabāŔanas periods ir atkarÄ«gs no rakstÄ«Å”anas intensitātes Å”ajā tēmā; Kafka ļauj elastÄ«gi iestatÄ«t uzglabāŔanas laika un datu apjoma ierobežojumus. IntensÄ«vām tēmām ir svarÄ«gi, lai visiem patērētājiem bÅ«tu laiks izlasÄ«t informāciju, pirms tā pazÅ«d, pat Ä«slaicÄ«gas nedarboÅ”anās gadÄ«jumā. Parasti ir iespējams saglabāt datus par dienu vienÄ«bas, kas ir pilnÄ«gi pietiekami atbalstam.

Pieredze pakalpojuma Refund Tool izstrādē ar asinhrono API vietnē Kafka

Tālāk neliels dokumentācijas pārstāsts, tiem, kam Kafka nav pazīstama (bilde arī no dokumentācijas)

AMQP ir rindas: mēs rakstām ziņojumus uz rindu patērētājam. Parasti vienu rindu apstrādā viena sistēma ar tādu paÅ”u biznesa loÄ£iku. Ja jums ir jāinformē vairākas sistēmas, varat iemācÄ«t lietojumprogrammai rakstÄ«t vairākās rindās vai konfigurēt apmaiņu ar fanout mehānismu, kas pats tās klonē.

Kafkam ir lÄ«dzÄ«ga abstrakcija temats, kurā rakstāt ziņas, taču tās pēc izlasÄ«Å”anas nepazÅ«d. Pēc noklusējuma, kad izveidojat savienojumu ar Kafka, jÅ«s saņemat visus ziņojumus un jums ir iespēja saglabāt no vietas, kur pārtraucāt. Tas ir, jÅ«s lasāt secÄ«gi, varat neatzÄ«mēt ziņojumu kā lasÄ«tu, bet saglabāt id, no kura varat turpināt lasÄ«t. Id, kuru izmantojāt, sauc par nobÄ«di, un mehānisms ir nobÄ«de.

AttiecÄ«gi var Ä«stenot dažādu loÄ£iku. Piemēram, mums ir BOB 4 gadÄ«jumos dažādām valstÄ«m - Lamoda ir Krievijā, Kazahstānā, Ukrainā, Baltkrievijā. Tā kā tie tiek izvietoti atseviŔķi, tiem ir nedaudz atŔķirÄ«gas konfigurācijas un sava biznesa loÄ£ika. Mēs ziņojumā norādām, uz kuru valsti tas attiecas. Katrs BOB patērētājs katrā valstÄ« lasa ar atŔķirÄ«gu groupId, un, ja ziņojums uz viņu neattiecas, viņi to izlaiž, t.i. nekavējoties veic nobÄ«di +1. Ja to paÅ”u tēmu lasa mÅ«su Maksājumu dienests, tas to dara ar atseviŔķu grupu, un tāpēc ieskaiti nekrustojas.

Pasākuma prasības:

  • Datu pilnÄ«gums. Es vēlētos, lai pasākumam bÅ«tu pietiekami daudz datu, lai to varētu apstrādāt.

  • Integritāte. Mēs deleģējam Events-bus pārbaudi, vai notikums ir konsekvents un var to apstrādāt.
  • KārtÄ«ba ir svarÄ«ga. AtgrieÅ”anās gadÄ«jumā esam spiesti strādāt ar vēsturi. Ar paziņojumiem pasÅ«tÄ«jums nav svarÄ«gs, ja tie ir viendabÄ«gi paziņojumi, e-pasts bÅ«s vienāds neatkarÄ«gi no tā, kurÅ” pasÅ«tÄ«jums ieradās pirmais. Naudas atmaksas gadÄ«jumā ir skaidrs process, ja mainÄ«sim pasÅ«tÄ«jumu, radÄ«sies izņēmumi, atmaksa netiks izveidota vai apstrādāta - mēs nonāksim citā statusā.
  • Konsekvence. Mums ir veikals, un tagad mēs veidojam notikumus, nevis API. Mums ir nepiecieÅ”ams veids, kā ātri un lēti pārsÅ«tÄ«t mÅ«su pakalpojumos informāciju par jauniem notikumiem un izmaiņām esoÅ”ajos. Tas tiek panākts, izmantojot kopÄ«gu specifikāciju atseviŔķā git repozitorijā un kodu Ä£eneratoros. Tāpēc klienti un serveri dažādos servisos tiek saskaņoti.

Kafka Lamodā

Mums ir trīs Kafka instalācijas:

  1. Baļķi;
  2. R&D;
  3. Pasākumi-autobuss.

Å odien mēs runājam tikai par pēdējo punktu. Pasākumos-busā mums nav Ä«paÅ”i lielas instalācijas - 3 brokeri (serveri) un tikai 27 tēmas. Parasti viena tēma ir viens process. Bet tas ir smalks punkts, un mēs to tagad pieskarsim.

Pieredze pakalpojuma Refund Tool izstrādē ar asinhrono API vietnē Kafka

AugÅ”pusē ir rps grafiks. Atmaksas process ir atzÄ«mēts ar tirkÄ«za lÄ«niju (jā, uz X ass), un rozā lÄ«nija ir satura atjaunināŔanas process.

Lamoda katalogā ir miljoniem produktu, un dati tiek pastāvÄ«gi atjaunināti. Dažas kolekcijas iziet no modes, to vietā tiek izlaistas jaunas, un katalogā pastāvÄ«gi parādās jauni modeļi. Mēs cenÅ”amies paredzēt, kas mÅ«su klientiem bÅ«s interesants rÄ«t, tāpēc pastāvÄ«gi iegādājamies jaunas lietas, fotografējam tās un atjaunojam vitrÄ«nu.

Rozā virsotnes ir produktu atjauninājumi, tas ir, produktu izmaiņas. Redzams, ka puiÅ”i bildēja, bildēja, un tad atkal! ā€” ielādēja pasākumu paku.

Lamoda Events lietoŔanas gadījumi

Mēs izmantojam konstruēto arhitektÅ«ru Ŕādām darbÄ«bām:

  • AtgrieÅ”anas statusa izsekoÅ”ana: aicinājums uz darbÄ«bu un statusa izsekoÅ”ana no visām iesaistÄ«tajām sistēmām. Maksājums, statusi, fiskalizācija, paziņojumi. Å eit mēs pārbaudÄ«jām pieeju, izveidojām rÄ«kus, savācām visas kļūdas, rakstÄ«jām dokumentāciju un stāstÄ«jām saviem kolēģiem, kā to izmantot.
  • Produktu karÅ”u atjaunināŔana: konfigurācija, metadati, raksturlielumi. Viena sistēma lasa (kas tiek parādÄ«ta) un vairākas raksta.
  • E-pasts, push un sms: pasÅ«tÄ«jums ir savākts, pasÅ«tÄ«jums ir pienācis, atgrieÅ”ana ir pieņemta utt., to ir daudz.
  • Krājumu, noliktavas atjaunoÅ”ana ā€” preču kvantitatÄ«vs atjauninājums, tikai skaitļi: ieraÅ”anās noliktavā, atgrieÅ”ana. Ir nepiecieÅ”ams, lai visas sistēmas, kas saistÄ«tas ar preču rezervÄ“Å”anu, darbotos ar jaunākajiem datiem. PaÅ”laik krājumu atjaunināŔanas sistēma ir diezgan sarežģīta, Kafka to vienkārÅ”os.
  • Datu analÄ«ze (R&D nodaļa), ML rÄ«ki, analÄ«tika, statistika. Mēs vēlamies, lai informācija bÅ«tu caurspÄ«dÄ«ga ā€“ Kafka tam ir labi piemērots.

Tagad interesantākā daļa par lielajiem izciļņiem un interesantiem atklājumiem, kas notikuÅ”i pēdējā pusgada laikā.

Dizaina problēmas

Pieņemsim, ka vēlamies veikt jaunu lietu ā€“ piemēram, nodot visu piegādes procesu Kafkai. Tagad daļa no procesa ir ieviesta pasÅ«tÄ«jumu apstrādē BOB. PasÅ«tÄ«juma nodoÅ”anas piegādes dienestam, pārvietoÅ”anas uz starpnoliktavu un tā tālāk ir statusa modelis. Ir vesels monolÄ«ts, pat divi, kā arÄ« daudz API, kas paredzēti piegādei. Viņi zina daudz vairāk par piegādi.

Å Ä·iet, ka Ŕīs jomas ir lÄ«dzÄ«gas, taču pasÅ«tÄ«jumu apstrādei BOB un piegādes sistēmai ir atŔķirÄ«gi statusi. Piemēram, daži kurjerpakalpojumi nesÅ«ta starpposma statusus, bet tikai galÄ«gos: ā€œpiegādātsā€ vai ā€œpazaudētsā€. Citi, gluži pretēji, ļoti detalizēti ziņo par preču apriti. Katram ir savi validācijas noteikumi: dažiem e-pasts ir derÄ«gs, kas nozÄ«mē, ka tas tiks apstrādāts; citiem tas nav derÄ«gs, bet pasÅ«tÄ«jums tik un tā tiks apstrādāts, jo ir telefona numurs saziņai, un kāds teiks, ka Ŕāds pasÅ«tÄ«jums netiks apstrādāts vispār.

Datu straume

Kafkas gadÄ«jumā rodas jautājums par datu plÅ«smas organizÄ“Å”anu. Å is uzdevums ietver stratēģijas izvēli, pamatojoties uz vairākiem punktiem; apskatÄ«sim tos visus.

Vienā tēmā vai dažādās?

Mums ir pasākuma specifikācija. BOB ierakstām, ka jāpiegādā tāds un tāds pasÅ«tÄ«jums, un norādām: pasÅ«tÄ«juma numuru, tā sastāvu, dažus SKU un svÄ«trkodus utt. Precēm nonākot noliktavā, piegāde varēs saņemt statusus, laika zÄ«mogus un visu nepiecieÅ”amo. Bet tad mēs vēlamies saņemt atjauninājumus par Å”iem datiem BOB. Mums ir apgriezts datu saņemÅ”anas process no piegādes. Vai tas ir tas pats pasākums? Vai arÄ« Ŕī ir atseviŔķa apmaiņa, kas ir pelnÄ«jusi savu tēmu?

Visticamāk, tie bÅ«s ļoti lÄ«dzÄ«gi, un kārdinājums taisÄ«t vienu tēmu nav nepamatots, jo atseviŔķa tēma nozÄ«mē atseviŔķus patērētājus, atseviŔķas konfigurācijas, atseviŔķu Ä£enerÄ“Å”anu tam visam. Bet ne fakts.

Jauns lauks vai jauns pasākums?

Bet, ja izmantojat tos paÅ”us notikumus, rodas cita problēma. Piemēram, ne visas piegādes sistēmas var Ä£enerēt tādu DTO, kādu var Ä£enerēt BOB. Mēs viņiem nosÅ«tām ID, bet viņi to nesaglabā, jo viņiem tas nav vajadzÄ«gs, un no notikumu kopnes procesa sākÅ”anas viedokļa Å”is lauks ir obligāts.

Ja mēs ievieÅ”am notikumu kopnes noteikumu, ka Å”is lauks ir obligāts, mēs esam spiesti iestatÄ«t papildu validācijas noteikumus BOB vai sākuma notikumu apdarinātājā. Validācija sāk izplatÄ«ties visā pakalpojumā - tas nav ļoti ērti.

Vēl viena problēma ir kārdinājums pakāpeniski attÄ«stÄ«ties. Mums saka, ka kaut kas ir jāpapildina ar pasākumu, un varbÅ«t, ja tā padomājam, tam vajadzēja bÅ«t atseviŔķam pasākumam. Bet mÅ«su shēmā atseviŔķs pasākums ir atseviŔķa tēma. AtseviŔķa tēma ir viss iepriekÅ” aprakstÄ«tais process. Izstrādātājam ir kārdinājums vienkārÅ”i pievienot citu lauku JSON shēmai un to atjaunot.

Naudas atmaksas gadÄ«jumā notikumu pasākumā ieradāmies pusgada laikā. Mums bija viens meta-notikums, ko sauc par atmaksas atjauninājumu, kurā bija tipa lauks, kurā aprakstÄ«ts, kas patiesÄ«bā ir Å”is atjauninājums. Tāpēc mums bija ā€œbrÄ«niŔķīgiā€ slēdži ar pārbaudÄ«tājiem, kuri mums pastāstÄ«ja, kā apstiprināt Å”o notikumu ar Ŕāda veida palÄ«dzÄ«bu.

Notikuma versiju veidoŔana

Lai apstiprinātu ziņojumus Kafkā, varat izmantot Avro, bet vajadzēja uzreiz uz tā likt un lietot Confluent. MÅ«su gadÄ«jumā mums jābÅ«t uzmanÄ«giem ar versiju veidoÅ”anu. Ne vienmēr bÅ«s iespējams atkārtoti nolasÄ«t ziņojumus no replikācijas žurnāla, jo modelis ir ā€œpalicisā€. BÅ«tÄ«bā izrādās, ka versijas ir jāveido tā, lai modelis bÅ«tu saderÄ«gs ar atpakaļejoÅ”u spēku: piemēram, uz laiku padariet lauku neobligātu. Ja atŔķirÄ«bas ir pārāk lielas, mēs sākam rakstÄ«t jaunā tēmā un nododam klientus, kad viņi pabeidz lasÄ«t veco.

Garantēta nodalÄ«jumu lasÄ«Å”anas secÄ«ba

Tēmas Kafkas iekÅ”ienē ir sadalÄ«tas nodalÄ«jumos. Tas nav Ä«paÅ”i svarÄ«gi, kamēr mēs veidojam entÄ«tijas un biržas, taču tas ir svarÄ«gi, lemjot, kā to patērēt un mērogot.

Parastā gadÄ«jumā tu raksti vienu tēmu Kafkā. Pēc noklusējuma tiek izmantots viens nodalÄ«jums, un visi ziņojumi Å”ajā tēmā tiek novirzÄ«ti uz to. LÄ«dz ar to patērētājs Å”os ziņojumus lasa secÄ«gi. Teiksim, tagad sistēma ir jāpaplaÅ”ina, lai ziņojumus lasÄ«tu divi dažādi patērētāji. Ja, piemēram, sÅ«tāt SMS, varat likt Kafkai izveidot papildu nodalÄ«jumu, un Kafka sāks sadalÄ«t ziņojumus divās daļās - puse Å”eit, puse Å”eit.

Kā Kafka tos sadala? Katram ziņojumam ir pamatteksts (kurā mēs glabājam JSON) un atslēga. Šai atslēgai varat pievienot jaucējfunkciju, kas noteiks, kurā nodalījumā ziņojums tiks nosūtīts.

MÅ«su gadÄ«jumā ar atmaksām tas ir svarÄ«gi, ja ņemam divus nodalÄ«jumus, tad pastāv iespēja, ka paralēlais patērētājs apstrādās otro notikumu pirms pirmā un bÅ«s nepatikÅ”anas. JaukÅ”anas funkcija nodroÅ”ina, ka ziņojumi ar vienu un to paÅ”u atslēgu nonāk tajā paŔā nodalÄ«jumā.

Notikumi vs komandas

Å Ä« ir vēl viena problēma, ar kuru mēs saskārāmies. Notikums ir noteikts notikums: mēs sakām, ka kaut kur kaut kas noticis (something_nopped), piemēram, prece tika atcelta vai atmaksāta nauda. Ja kāds klausās Å”os notikumus, saskaņā ar ā€œprece cancelledā€ tiks izveidota atmaksas vienÄ«ba un kaut kur iestatÄ«jumos tiks ierakstÄ«ts ā€œatmaksa notikusiā€.

Bet parasti, plānojot pasākumus, jÅ«s nevēlaties tos rakstÄ«t velti - jÅ«s paļaujaties uz to, ka kāds tos izlasÄ«s. Pastāv liels kārdinājums rakstÄ«t nevis kaut ko_noticis (prece_canceled, refund_refunded), bet kaut ko_vajadzētu_izdarÄ«t. Piemēram, prece ir gatava atgrieÅ”anai.

No vienas puses, tas liecina, kā pasākums tiks izmantots. No otras puses, tas daudz mazāk izklausās pēc parasta notikuma nosaukuma. Turklāt tas nav tālu lÄ«dz komandai do_something. Bet jums nav garantijas, ka kāds izlasÄ«s Å”o notikumu; un ja izlasi, tad veiksmÄ«gi izlasÄ«ji; un ja tu to veiksmÄ«gi izlasÄ«ji, tad kaut ko izdarÄ«ji, un tas kaut kas izdevās. BrÄ«dÄ«, kad notikums kļūst par kaut ko darÄ«t, ir nepiecieÅ”ama atgriezeniskā saite, un tā ir problēma.

Pieredze pakalpojuma Refund Tool izstrādē ar asinhrono API vietnē Kafka

RabbitMQ asinhronajā apmaiņā, izlasot ziņojumu, dodieties uz http, jums ir atbilde - vismaz, ka ziņojums tika saņemts. Kad tu raksti Kafkai, parādās ziņa, ko tu rakstīji Kafkai, bet tu neko nezini par to, kā tas tika apstrādāts.

LÄ«dz ar to mÅ«su gadÄ«jumā nācās ieviest atbildes notikumu un izveidot monitoringu, lai, ja tiktu nosÅ«tÄ«ts tik daudz notikumu, pēc tāda un tāda laika pienāktu tikpat daudz atbildes notikumu. Ja tas nenotiek, tad Ŕķiet, ka kaut kas ir nogājis greizi. Piemēram, ja mēs nosÅ«tÄ«jām notikumu ā€œitem_ready_to_refundā€, mēs sagaidām, ka tiks izveidota atmaksa, nauda tiks atgriezta klientam un mums tiks nosÅ«tÄ«ts pasākums ā€œmoney_refundedā€. Bet tas nav droÅ”i, tāpēc ir nepiecieÅ”ama uzraudzÄ«ba.

Nianses

Pastāv diezgan acīmredzama problēma: ja jūs lasāt no tēmas secīgi un jums ir slikta ziņa, patērētājs kritīs, un jūs netiksit tālāk. Tev vajag apturēt visus patērētājus, veiciet nobīdi tālāk, lai turpinātu lasīt.

Mēs par to zinājām, ar to rēķinājāmies, un tomēr tas notika. Un tas notika tāpēc, ka notikums bija derÄ«gs no notikumu-bus viedokļa, notikums bija derÄ«gs no lietojumprogrammu validatora viedokļa, bet tas nebija derÄ«gs no PostgreSQL viedokļa, jo mÅ«su sistēmā MySQL ar UNSIGNED INT sistēmā bija PostgreSQL tikai ar INT. Viņa izmērs ir nedaudz mazāks, un ID nederēja. Simfonijs nomira ar izņēmumu. Mēs, protams, uztvērām izņēmumu, jo paļāvāmies uz to un gatavojāmies veikt Å”o nobÄ«di, taču pirms tam mēs vēlējāmies palielināt problēmu skaitÄ«tāju, jo ziņojums tika apstrādāts neveiksmÄ«gi. ArÄ« Ŕī projekta skaitÄ«tāji ir datu bāzē, un Symfony jau ir slēdzis saziņu ar datu bāzi, un otrais izņēmums nogalināja visu procesu bez iespējas veikt kompensāciju.

Serviss kādu laiku nogulēja - par laimi ar Kafku nav tik slikti, jo ziņas paliek. Kad darbs ir atjaunots, varat pabeigt to lasÄ«Å”anu. Tas ir ērti.

Kafka spēj iestatÄ«t patvaļīgu nobÄ«di, izmantojot instrumentus. Bet, lai to izdarÄ«tu, jums ir jāaptur visi patērētāji - mÅ«su gadÄ«jumā sagatavojiet atseviŔķu laidienu, kurā nebÅ«s patērētāju, pārdalÄ«Å”anas. Pēc tam programmā Kafka varat novirzÄ«t nobÄ«di, izmantojot instrumentus, un ziņojums tiks nosÅ«tÄ«ts.

Vēl viena nianse - replikācijas žurnāls vs rdkafka.so - ir saistÄ«ts ar mÅ«su projekta specifiku. Mēs izmantojam PHP, un PHP, kā likums, visas bibliotēkas sazinās ar Kafku caur rdkafka.so repozitoriju, un tad ir kaut kāds iesaiņojums. VarbÅ«t tās ir mÅ«su personÄ«gās grÅ«tÄ«bas, bet izrādÄ«jās, ka vienkārÅ”i pārlasÄ«t kādu gabalu no jau izlasÄ«tā nav nemaz tik viegli. Kopumā bija programmatÅ«ras problēmas.

Atgriežoties pie darba ar starpsienām specifikas, tas ir rakstÄ«ts tieÅ”i dokumentācijā patērētāji >= tēmu nodalÄ«jumi. Bet es par to uzzināju daudz vēlāk, nekā es vēlētos. Ja vēlaties mērogot un jums ir divi patērētāji, jums ir nepiecieÅ”ami vismaz divi nodalÄ«jumi. Tas ir, ja jums bija viens nodalÄ«jums, kurā bija uzkrājuÅ”ies 20 tÅ«kstoÅ”i ziņojumu, un jÅ«s izveidojāt jaunu, ziņojumu skaits drÄ«z netiks izlÄ«dzināts. Tāpēc, lai bÅ«tu divi paralēli patērētāji, jums jārÄ«kojas ar starpsienām.

Uzraudzība

Es domāju, ka tas, kā mēs to uzraudzÄ«sim, bÅ«s vēl skaidrāks, kādas problēmas ir esoÅ”ajā pieejā.

Piemēram, mēs aprēķinām, cik produktu datubāzē nesen ir mainÄ«juÅ”i statusu, un attiecÄ«gi notikumiem, pamatojoties uz Ŕīm izmaiņām, bija jānotiek, un mēs nosÅ«tām Å”o numuru mÅ«su uzraudzÄ«bas sistēmai. Tad no Kafkas mēs iegÅ«stam otro numuru, cik notikumu faktiski tika ierakstÄ«ti. AcÄ«mredzot atŔķirÄ«bai starp Å”iem diviem skaitļiem vienmēr jābÅ«t nullei.

Pieredze pakalpojuma Refund Tool izstrādē ar asinhrono API vietnē Kafka

Turklāt jums ir jāuzrauga, kā klājas ražotājam, vai notikumi-bus saņemtie ziņojumi un kā klājas patērētājam. Piemēram, zemāk redzamajās diagrammās Atmaksas rīks darbojas labi, bet BOB acīmredzami ir dažas problēmas (zilas virsotnes).

Pieredze pakalpojuma Refund Tool izstrādē ar asinhrono API vietnē Kafka

Es jau minēju patērētāju grupas nobīdi. Aptuveni runājot, tas ir nelasīto ziņojumu skaits. Kopumā mūsu patērētāji strādā ātri, tāpēc nobīde parasti ir 0, bet dažreiz var būt īslaicīgs maksimums. Kafka to var izdarīt no kastes, taču jums ir jāiestata noteikts intervāls.

Ir projekts BurzÄ«tieskas sniegs jums vairāk informācijas par Kafku. Tā vienkārÅ”i izmanto patērētāju grupas API, lai sniegtu statusu, kā Å”ai grupai veicas. Papildus OK un Failed ir brÄ«dinājums, un jÅ«s varat uzzināt, ka jÅ«su patērētāji nevar tikt galā ar ražoÅ”anas tempu - viņiem nav laika rakstÄ«tā korektÅ«ru. Sistēma ir diezgan gudra un viegli lietojama.

Pieredze pakalpojuma Refund Tool izstrādē ar asinhrono API vietnē Kafka

Šādi izskatās API atbilde. Šeit ir grupa bob-live-fifa, partition refund.update.v1, statuss OK, lag 0 - pēdējā gala nobīde tāda un tāda.

Pieredze pakalpojuma Refund Tool izstrādē ar asinhrono API vietnē Kafka

UzraudzÄ«ba updated_at SLA (iestrēdzis) Es jau minēju. Piemēram, prece ir mainÄ«jusies uz statusu, ka tā ir gatava atgrieÅ”anai. Instalējam Cron, kas saka, ja 5 minÅ«Å”u laikā Å”is objekts nav aizgājis uz atmaksu (ļoti ātri atdodam naudu caur maksājumu sistēmām), tad kaut kas noteikti nogāja greizi, un Å”is noteikti ir atbalsta gadÄ«jums. Tāpēc mēs vienkārÅ”i ņemam Cron, kas nolasa Ŕādas lietas, un, ja tās ir lielākas par 0, tad tas nosÅ«ta brÄ«dinājumu.

Rezumējot, notikumu izmantoÅ”ana ir ērta, kad:

  • informācija ir nepiecieÅ”ama vairākām sistēmām;
  • apstrādes rezultāts nav svarÄ«gs;
  • ir maz pasākumu vai nelielu notikumu.

Šķiet, ka rakstam ir ļoti specifiska tēma - asinhronā API uz Kafka, bet saistībā ar to es gribētu ieteikt daudzas lietas uzreiz.
Pirmkārt, nākamais HighLoad++ jāgaida līdz novembrim, aprīlī būs Sanktpēterburgas versija, un jūnijā runāsim par lielām slodzēm Novosibirskā.
Otrkārt, ziņojuma autors Sergejs Zaika ir mÅ«su jaunās zināŔanu pārvaldÄ«bas konferences programmu komitejas loceklis. KnowledgeConf. Konference ir vienas dienas, notiks 26.aprÄ«lÄ«, bet tās programma ir ļoti spraiga.
Un tas bÅ«s maijā PHP Krievija Šø RIT++ (ar iekļautu DevOpsConf) - jÅ«s varat arÄ« ieteikt savu tēmu tur, runāt par savu pieredzi un sÅ«dzēties par saviem pildÄ«tajiem čiekuriem.

Avots: www.habr.com

Pievieno komentāru