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.
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Ä.
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.
MÅ«su motivÄcija:
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.
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.
Å Ä« 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.
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.
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).
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.
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.
Å 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.
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.
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.
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:
Baļķi;
R&D;
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.
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.
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.
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.
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).
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.
Å Ä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.
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.