Python vaidmuo įvykiais valdomoje architektūroje: pranešimais pagrįsta komunikacija keičiamoms, atsparioms ir atjungtoms sistemoms. Modeliai, įrankiai ir praktika.
Python įvykiais valdoma architektūra: pranešimais pagrįsto ryšio įvaldymas
Šiandieniniame sparčiai besivystančiame skaitmeniniame kraštovaizdyje itin svarbu kurti programinės įrangos sistemas, kurios būtų ne tik funkcionalios, bet ir keičiamos, atsparios bei lanksčios. Įvykiais valdoma architektūra (angl. Event-Driven Architecture, EDA) tapo galinga paradigma šiems tikslams pasiekti. Iš esmės EDA sukasi apie įvykių generavimą, aptikimą, vartojimą ir reagavimą į juos. Šiame išsamiame vadove mes gilinsimės į įvykiais valdomų architektūrų diegimo niuansus naudojant Python, ypatingą dėmesį skirdami pranešimais pagrįstam ryšiui. Išnagrinėsime pagrindines sąvokas, populiarius įrankius, projektavimo modelius ir praktinius aspektus, kurie leis jums kurti sudėtingas, atskirtas sistemas.
Kas yra įvykiais valdoma architektūra (EDA)?
Įvykiais valdoma architektūra yra programinės įrangos projektavimo modelis, skatinantis įvykių generavimą, aptikimą, vartojimą ir reagavimą į juos. Įvykis yra reikšmingas būsenos pasikeitimas. Pavyzdžiui, kliento pateiktas užsakymas, jutiklio aptiktas temperatūros slenkstis arba vartotojo mygtuko paspaudimas gali būti laikomi įvykiais.
EDA sistemoje komponentai bendrauja generuodami ir vartodami įvykius. Tai skiriasi nuo tradicinių užklausos-atsakymo architektūrų, kuriose komponentai tiesiogiai iškviečia vienas kitą. Pagrindinės EDA savybės:
- Asinchroninis ryšys: Įvykiai paprastai apdorojami asinchroniškai, o tai reiškia, kad gamintojas nelaukia, kol vartotojas patvirtins arba apdoros įvykį, prieš tęsdamas savo darbą.
- Atskyrimas: Komponentai yra laisvai susieti. Gamintojams nereikia žinoti, kas yra vartotojai, o vartotojams nereikia žinoti, kas yra gamintojai. Jiems tereikia susitarti dėl įvykio formato ir ryšio kanalo.
- Reaktyvumas: Sistemos gali greitai reaguoti į būsenos pokyčius, kai įvykiai paskleidžiami per sistemą.
- Keičiamumas ir atsparumas: Atskiriant komponentus, atskiros paslaugos gali būti keičiamos nepriklausomai, o vieno komponento gedimas rečiau sugriaus visą sistemą.
Pranešimais pagrįsto ryšio vaidmuo EDA
Pranešimais pagrįstas ryšys yra daugumos įvykiais valdomų architektūrų pagrindas. Jis suteikia infrastruktūrą, kad įvykiai būtų patikimai ir efektyviai perduodami iš gamintojų vartotojams. Paprastai pranešimas yra duomenų fragmentas, atspindintis įvykį.
Pagrindiniai pranešimais pagrįsto ryšio komponentai:
- Įvykių gamintojai: Programos ar paslaugos, kurios generuoja įvykius ir publikuoja juos kaip pranešimus.
- Įvykių vartotojai: Programos ar paslaugos, kurios prenumeruoja tam tikrus įvykių tipus ir reaguoja, kai gauna atitinkamus pranešimus.
- Pranešimų tarpininkas/eilė: Tarpinė paslauga, kuri gauna pranešimus iš gamintojų ir pristato juos vartotojams. Šis komponentas yra labai svarbus atskiriant ir valdant įvykių srautą.
Pranešimų tarpininkas veikia kaip centrinis mazgas, buferiuojantis pranešimus, užtikrinantis pristatymą ir leidžiantis keliems vartotojams apdoroti tą patį įvykį. Šis atsakomybių atskyrimas yra esminis kuriant patikimas paskirstytas sistemas.
Kodėl Python tinka įvykiais valdomoms architektūroms?
Python populiarumas ir jo turtinga ekosistema daro jį puikiu pasirinkimu kuriant įvykiais valdomas sistemas. Keletas veiksnių prisideda prie jo tinkamumo:
- Skaitomumas ir paprastumas: Aiški Python sintaksė ir naudojimo paprastumas pagreitina kūrimą ir palengvina kodo priežiūrą, ypač sudėtingose paskirstytose aplinkose.
- Didžiulės bibliotekos ir karkasai: Python turi didelę bibliotekų kolekciją tinklaveikai, asinchroniniam programavimui ir integracijai su pranešimų tarpininkais.
- Asinchroninio programavimo palaikymas: Integruotas Python palaikymas
asyncio, kartu su tokiomis bibliotekomis kaipaiohttpirhttpx, leidžia lengvai rašyti neužblokuojantį, asinchroninį kodą, kuris yra būtinas EDA. - Stipri bendruomenė ir dokumentacija: Didelė ir aktyvi bendruomenė reiškia gausius išteklius, mokymo programas ir lengvai prieinamą palaikymą.
- Integracijos galimybės: Python lengvai integruojasi su įvairiomis technologijomis, įskaitant duomenų bazes, debesų paslaugas ir esamas įmonių sistemas.
Pagrindinės Python EDA su pranešimais pagrįstu ryšiu sąvokos
1. Įvykiai ir pranešimai
EDA, įvykis yra faktinis teiginys apie tai, kas nutiko. Pranešimas yra konkreti duomenų struktūra, kuri perduoda šią įvykio informaciją. Pranešimuose paprastai yra:
- Įvykio tipas: Aiškus identifikatorius, kas nutiko (pvz., „UžsakymasPateiktas“, „VartotojasPrisijungė“, „MokėjimasApdorotas“).
- Įvykio duomenys: Naudingoji apkrova, kurioje yra susijusi informacija apie įvykį (pvz., užsakymo ID, vartotojo ID, mokėjimo suma).
- Laiko žyma: Kada įvyko įvykis.
- Šaltinis: Sistema arba komponentas, kuris sugeneravo įvykį.
Python žodynai arba pasirinktinės klasės dažniausiai naudojamos įvykių duomenims atvaizduoti. Duomenų perdavimui pranešimams struktūrizuoti dažnai naudojami serializavimo formatai, tokie kaip JSON arba Protocol Buffers.
2. Pranešimų tarpininkai ir eilės
Pranešimų tarpininkai yra daugelio EDA centrinė nervų sistema. Jie atskiria gamintojus nuo vartotojų ir valdo pranešimų srautą.
Dažniausiai naudojami pranešimų siuntimo modeliai:
- Taškas-į-tašką (eilės): Pranešimas pristatomas vienam vartotojui. Naudinga užduočių paskirstymui.
- Publikuoti/Prenumeruoti (temos): Į temą publikuotas pranešimas gali būti gautas kelių prenumeratorių, besidominčių ta tema. Idealiai tinka įvykių transliavimui.
Populiarūs pranešimų tarpininkai, kurie gerai integruojasi su Python:
- RabbitMQ: Patikimas, atvirojo kodo pranešimų tarpininkas, palaikantis įvairius pranešimų siuntimo protokolus (AMQP, MQTT, STOMP) ir siūlantis lanksčias maršrutizavimo galimybes.
- Apache Kafka: Paskirstyta įvykių srautinio perdavimo platforma, sukurta dideliam pralaidumui, atsparumui gedimams ir realaus laiko duomenų srautams. Puikiai tinka srautiniam apdorojimui ir įvykių šaltinių nustatymui.
- Redis Streams: „Redis“ duomenų struktūra, leidžianti naudoti tik pridėjimo žurnalus, veikianti kaip lengvas pranešimų tarpininkas tam tikriems naudojimo atvejams.
- AWS SQS (Simple Queue Service) ir SNS (Simple Notification Service): Debesų pagrindu veikiančios valdomos paslaugos, siūlančios eilių ir publikavimo/prenumeravimo galimybes.
- Google Cloud Pub/Sub: Valdoma, asinchroninė pranešimų paslauga, leidžianti siųsti ir gauti pranešimus tarp nepriklausomų programų.
3. Asinchroninis programavimas naudojant `asyncio`
Python biblioteka `asyncio` yra nepakeičiama kuriant efektyvias įvykiais valdomas programas. Ji leidžia rašyti lygiagretų kodą naudojant `async/await` sintaksę, kuri yra neužblokuojanti ir labai efektyvi I/O operacijoms, tokioms kaip tinklo ryšys su pranešimų tarpininkais.
Tipiškas `asyncio` gamintojas gali atrodyti taip:
import asyncio
import aio_pika # Example for RabbitMQ
async def send_event(queue_name, message_data):
connection = await aio_pika.connect_robust("amqp://guest:guest@localhost/")
async with connection:
channel = await connection.channel()
await channel.declare_queue(queue_name)
message = aio_pika.Message(body=message_data.encode())
await channel.default_exchange.publish(message, routing_key=queue_name)
print(f"Sent message: {message_data}")
async def main():
await send_event("my_queue", '{"event_type": "UserCreated", "user_id": 123}')
if __name__ == "__main__":
asyncio.run(main())
Ir vartotojas:
import asyncio
import aio_pika
async def consume_events(queue_name):
connection = await aio_pika.connect_robust("amqp://guest:guest@localhost/")
async with connection:
channel = await connection.channel()
queue = await channel.declare_queue(queue_name)
async with queue.iterator() as queue_iter:
async for message in queue_iter:
async with message.process():
print(f"Received message: {message.body.decode()}")
# Process the event here
async def main():
await consume_events("my_queue")
if __name__ == "__main__":
asyncio.run(main())
4. Atskyrimas ir keičiamumas naudojant mikroservisus
EDA puikiai tinka mikroservisų architektūroms. Kiekvienas mikroservisas gali veikti kaip įvykių gamintojas ir (arba) vartotojas, bendraujantis su kitomis paslaugomis per pranešimų tarpininką. Tai leidžia:
- Nepriklausomas kūrimas ir diegimas: Komandos gali dirbti ir diegti paslaugas nepriklausomai.
- Technologijų įvairovė: Skirtingos paslaugos gali būti parašytos skirtingomis kalbomis, nors vis dar būtinas bendras pranešimo formatas.
- Granuliuotas keičiamumas: Didelį krūvį patiriančios paslaugos gali būti išplėstos nepaveikiant kitų.
- Gedimų izoliavimas: Vieno mikroserviso gedimas rečiau kaskadomis paveiks visą sistemą.
Pavyzdžiui, el. prekybos platforma gali turėti paslaugas, skirtas „Užsakymų valdymui“, „Atsargoms“, „Mokėjimų apdorojimui“ ir „Pristatymui“. Kai pateikiamas užsakymas (įvykis „UžsakymasPateiktas“), Užsakymų valdymo paslauga publikuoja šį įvykį. Atsargų paslauga jį sunaudoja atsargoms atnaujinti, Mokėjimo paslauga – mokėjimui inicijuoti, o Pristatymo paslauga – paruošimui išsiųsti.
Populiarios Python bibliotekos pranešimų tarpininkams
Panagrinėkime kai kurias plačiausiai naudojamas Python bibliotekas, skirtas sąveikai su pranešimų tarpininkais:
1. `pika` ir `aio-pika` skirtos RabbitMQ
pika yra oficialus, sinchroninis „RabbitMQ“ klientas. Asinchroninėms programoms, sukurtoms naudojant `asyncio`, aio-pika yra tinkamiausias pasirinkimas. Ji teikia asinchroninę API pranešimų publikavimui ir vartojimui.
Naudojimo atvejai: Užduočių eilės, paskirstytas užduočių apdorojimas, realaus laiko pranešimai, sudėtingų pranešimų srautų maršrutizavimas.
2. `kafka-python` ir `confluent-kafka-python` skirtos Apache Kafka
kafka-python yra plačiai naudojamas, grynas Python klientas, skirtas „Kafka“. confluent-kafka-python, sukurta remiantis `librdkafka`, siūlo didesnį našumą ir išsamesnį funkcijų rinkinį, dažnai teikiamą pirmenybę gamybos aplinkose.
Naudojimo atvejai: Realaus laiko duomenų kanalai, žurnalų agregavimas, įvykių šaltinių nustatymas, srautinio perdavimo apdorojimas, didelio masto duomenų įkėlimas.
3. `redis-py` skirta Redis Streams
Nors „Redis“ visų pirma yra raktų ir reikšmių saugykla, ji siūlo galingą „Streams“ duomenų tipą, kuris gali būti naudojamas kaip lengvas pranešimų tarpininkas. Biblioteka redis-py suteikia prieigą prie šių galimybių.
Naudojimo atvejai: Paprastas publikavimas/prenumeravimas, realaus laiko analizė, talpyklos naudojimas su įvykių pranešimais, lengvas užduočių paskirstymas, kai pilnavertis tarpininkas gali būti perteklinis.
4. Debesų specifiniai SDK (Boto3 skirta AWS, Google Cloud kliento bibliotekos)
Debesų pagrindu veikiantiems diegimams dažnai paprasčiausias metodas yra naudoti debesų tiekėjų pateiktus SDK:
- Boto3 (AWS): Sąveikauja su AWS SQS, SNS, Kinesis ir kt.
- Google Cloud Client Libraries for Python: Sąveikauja su Google Cloud Pub/Sub.
Naudojimo atvejai: Valdomų debesų paslaugų panaudojimas keičiamumui, patikimumui ir sumažintoms veiklos sąnaudoms debesies aplinkose.
Dažniausiai pasitaikantys EDA projektavimo modeliai Python
Įtvirtintų projektavimo modelių taikymas yra labai svarbus kuriant prižiūrimas ir keičiamas įvykiais valdomas sistemas. Štai keletas pagrindinių modelių, dažniausiai diegiamų Python:
1. Įvykių pranešimas
Šiame modelyje įvykių gamintojas publikuoja įvykį, kad praneštų kitoms paslaugoms, jog kažkas nutiko. Pats įvykio pranešimas gali turėti minimalius duomenis, tiesiog tiek, kad būtų galima identifikuoti įvykį. Suinteresuoti įvykiu vartotojai tada gali užklausti gamintojo arba bendros duomenų saugyklos dėl išsamesnės informacijos.
Pavyzdys: Publikuojamas įvykis „ProduktasAtnaujintas“. „Paieškos indeksavimo“ paslauga apdoroja šį įvykį ir tada gauna visą produkto informaciją, kad atnaujintų savo paieškos indeksą.
Python implementacija: Naudokite „Pub/Sub“ sistemą (tokią kaip „Kafka“ temos arba SNS), kad transliuotumėte įvykius. Vartotojai naudoja pranešimų filtrus arba atlieka paieškas pagal įvykio ID.
2. Įvykiu perduodamos būsenos perdavimas
Čia įvykio pranešimas turi visus reikalingus duomenis, kad vartotojas galėtų atlikti savo veiksmą, nereikalaujant užklausti gamintojo. Tai padidina atskyrimą ir sumažina delsą.
Pavyzdys: Įvykis „UžsakymasPateiktas“ turi visą užsakymo informaciją (prekes, kiekius, kliento adresą, mokėjimo informaciją). „Pristatymo paslauga“ gali tiesiogiai naudoti šią informaciją, kad sukurtų siuntos etiketę.
Python implementacija: Užtikrinkite, kad įvykių naudingosios apkrovos būtų išsamios. Naudokite efektyvius serializavimo formatus (pvz., Protocol Buffers binariam efektyvumui) ir apsvarstykite duomenų nuoseklumo pasekmes.
3. Įvykių šaltinių nustatymas
Įvykių šaltinių nustatyme (angl. Event Sourcing) visi programos būsenos pokyčiai saugomi kaip nekintamų įvykių seka. Užuot saugoję dabartinę objekto būseną, saugote įvykių, kurie lėmė tą būseną, istoriją. Dabartinė būsena gali būti atkurta pakartotinai paleidus šiuos įvykius.
Pavyzdys: „Banko sąskaitos“ objektui, vietoj dabartinio balanso saugojimo, saugote įvykius, tokius kaip „SąskaitaSukurta“, „PinigaiĮnešti“, „PinigaiPaimti“. Balansas apskaičiuojamas sumuojant šiuos įvykius.
Python implementacija: Reikalinga patikima įvykių saugykla (dažnai specializuota duomenų bazė arba „Kafka“ tema). Įvykių vartotojai gali kurti projekcijas (skaitymo modelius) apdorodami įvykių srautą.
4. CQRS (komandų užklausų atsakomybės atskyrimas)
CQRS atskiria modelį, naudojamą būsenai atnaujinti (komandos), nuo modelio, naudojamo būsenai nuskaityti (užklausos). Dažnai naudojamas kartu su įvykių šaltinių nustatymu.
Pavyzdys: Vartotojas pateikia „SukurtiUžsakymą“ komandą. Ši komanda apdorojama, ir publikuojamas įvykis „UžsakymasSukurtas“. Atskira „UžsakymoSkaitymoModelio“ paslauga apdoroja šį įvykį ir atnaujina skaitymui optimizuotą duomenų bazę, kad efektyviai užklausinėtų užsakymo būseną.
Python implementacija: Naudokite atskiras paslaugas arba modulius komandų ir užklausų apdorojimui. Įvykių tvarkyklės yra atsakingos už skaitymo modelių atnaujinimą iš įvykių.
5. Saga modelis
Operacijoms, apimančioms kelis mikroservisus, Saga modelis valdo paskirstytas operacijas. Tai vietinių operacijų seka, kurioje kiekviena operacija atnaujina duomenų bazę ir publikuoja pranešimą arba įvykį, kad suaktyvintų kitą vietinę operaciją sagoje. Jei vietinė operacija nepavyksta, saga vykdo kompensacinių operacijų seriją, kad anuliuotų ankstesnes operacijas.
Pavyzdys: „Užsakymo“ procesas, apimantis „Mokėjimo“, „Atsargų“ ir „Pristatymo“ paslaugas. Jei „Pristatymas“ nepavyksta, saga inicijuoja kompensaciją, kad grąžintų mokėjimą ir atlaisvintų atsargas.
Python implementacija: Gali būti įdiegta per choreografiją (paslaugos reaguoja į viena kitos įvykius) arba orkestraciją (centrinė orkestravimo paslauga valdo sagos žingsnius).
Praktiniai aspektai Python EDA
Nors EDA siūlo didelius pranašumus, sėkmingam diegimui reikia kruopštaus planavimo ir kelių veiksnių apsvarstymo:
1. Įvykių schemos kūrimas ir versijavimas
Svarba: Vystantis jūsų sistemai, įvykių schemos keisis. Šių pakeitimų valdymas, nepažeidžiant esamų vartotojų, yra labai svarbus.
Strategijos:
- Naudokite schemų registrus: Įrankiai, tokie kaip „Confluent Schema Registry“ (skirta „Kafka“) arba pasirinktiniai sprendimai, leidžia jums valdyti įvykių schemas ir taikyti suderinamumo taisykles.
- Atgalinis ir į priekį suderinamumas: Kurkite įvykius taip, kad naujesnes versijas galėtų suprasti senesni vartotojai (atgalinis suderinamumas) ir senesnes versijas galėtų apdoroti naujesni vartotojai (į priekį suderinamumas).
- Venkite laužančių pakeitimų: Kai įmanoma, pridėkite naujus laukus, o ne pašalinkite ar pervardykite esamus.
- Aiškus versijavimas: Įtraukite versijos numerį į savo įvykio schemą arba pranešimo metaduomenis.
2. Klaidų tvarkymas ir pakartotiniai bandymai
Svarba: Paskirstytoje, asinchroninėje sistemoje gedimai yra neišvengiami. Patikimas klaidų tvarkymas yra labai svarbus.
Strategijos:
- Idempotentiškumas: Kurkite vartotojus taip, kad jie būtų idempotentūs, t. y., kad to paties pranešimo apdorojimas kelis kartus turėtų tokį patį efektą kaip ir vienkartinis apdorojimas. Tai labai svarbu pakartotinių bandymų mechanizmams.
- Mirušio laiško eilės (DLQs): Sukonfigūruokite pranešimų tarpininką, kad pranešimai, kurie nuolat nepavyksta apdoroti, būtų siunčiami į atskirą DLQ tyrimui.
- Pakartotinio bandymo politikos: Įdiekite eksponentinį atsitraukimą pakartotiniams bandymams, kad išvengtumėte pasroviui esančių paslaugų perkrovos.
- Stebėjimas ir įspėjimai: Nustatykite įspėjimus apie didelį DLQ dažnį arba nuolatinius apdorojimo gedimus.
3. Stebėjimas ir matomumas
Svarba: Suprasti įvykių srautą, nustatyti kliūtis ir diagnozuoti problemas paskirstytoje sistemoje yra sudėtinga be tinkamo matomumo.
Įrankiai ir praktika:
- Paskirstyta sekimo sistema: Naudokite įrankius, tokius kaip Jaeger, Zipkin arba OpenTelemetry, kad sektumėte užklausas ir įvykius per kelias paslaugas.
- Žurnalų fiksavimas: Centralizuotas žurnalų fiksavimas (pvz., ELK rinkinys, Splunk) yra būtinas visų paslaugų žurnalams agreguoti. Įtraukite koreliacijos ID į žurnalus, kad susietumėte įvykius.
- Metrikos: Stebėkite pagrindines metrikas, tokias kaip pranešimų pralaidumas, delsa, klaidų rodikliai ir eilių ilgiai. „Prometheus“ ir „Grafana“ yra populiarūs pasirinkimai.
- Sveikatos patikros: Įdiekite sveikatos patikros galinius taškus visoms paslaugoms.
4. Našumas ir pralaidumas
Svarba: Didelio srauto programoms, pranešimų apdorojimo našumo optimizavimas yra labai svarbus.
Strategijos:
- Asinchroninės operacijos: Naudokite Python `asyncio` neužblokuojančiam I/O.
- Pakavimas: Apdorokite pranešimus partijomis, kai įmanoma, kad sumažintumėte sąnaudas.
- Efektyvus serializavimas: Išmintingai pasirinkite serializavimo formatus (pvz., JSON, kad būtų lengva skaityti, Protocol Buffers arba Avro, kad būtų pasiektas našumas ir schemos vykdymas).
- Vartotojų mastelio keitimas: Keiskite vartotojų egzempliorių skaičių pagal pranešimų atsilikimą ir apdorojimo pajėgumus.
- Tarpininko derinimas: Sukonfigūruokite savo pranešimų tarpininką optimaliam našumui, atsižvelgiant į jūsų darbo krūvį.
5. Saugumas
Svarba: Komunikacijos kanalų ir pačių duomenų apsauga yra gyvybiškai svarbi.
Praktika:
- Autentifikavimas ir autorizavimas: Apsaugokite prieigą prie savo pranešimų tarpininko naudodami kredencialus, sertifikatus arba žetonais pagrįstą autentifikavimą.
- Šifravimas: Naudokite TLS/SSL, kad užšifruotumėte ryšį tarp gamintojų, vartotojų ir tarpininko.
- Duomenų patvirtinimas: Patikrinkite gaunamus pranešimus, ar juose nėra kenkėjiško turinio ar netinkamai suformuotų duomenų.
- Prieigos kontrolės sąrašai (ACL): Apibrėžkite, kurie klientai gali publikuoti ar prenumeruoti konkrečias temas ar eiles.
Pasauliniai EDA aspektai
Diegiant EDA pasauliniu mastu, atsiranda keletas unikalių iššūkių ir galimybių:
- Laiko juostos: Įvykiai dažnai turi laiko žymas. Užtikrinkite laiko juostų nuoseklumą ir tinkamą tvarkymą, kad užsakymas ir apdorojimas būtų tikslūs. Apsvarstykite galimybę naudoti Koordinuotąjį universalųjį laiką (UTC) kaip standartą.
- Vėlavimas: Tinklo vėlavimas tarp geografiškai paskirstytų paslaugų gali paveikti pranešimų pristatymo ir apdorojimo laiką. Pasirinkite pranešimų tarpininkus, turinčius regioninį prieinamumą, arba apsvarstykite daugelio regionų diegimus.
- Duomenų suverenitetas ir reglamentai: Skirtingos šalys turi skirtingus duomenų apsaugos įstatymus (pvz., GDPR, CCPA). Užtikrinkite, kad jūsų įvykių duomenų tvarkymas atitiktų šiuos reglamentus, ypač susijusius su asmens identifikavimo informacija (PII). Gali tekti saugoti arba apdoroti duomenis tam tikrose geografinėse ribose.
- Valiuta ir lokalizacija: Jei įvykiai apima finansines operacijas arba lokalizuotą turinį, užtikrinkite, kad jūsų pranešimų naudingosios apkrovos atitiktų skirtingas valiutas, kalbas ir regioninius formatus.
- Nelaimių atkūrimas ir verslo tęstinumas: Sukurkite savo EDA taip, kad ji būtų atspari regioniniams gedimams. Tai gali apimti daugelio regionų pranešimų tarpininkus ir dubliuotus paslaugų diegimus.
Pavyzdys: Tarptautinis el. prekybos užsakymo srautas
Vizualizuokime supaprastintą tarptautinio el. prekybos užsakymo srautą, naudojant EDA su Python:
- Vartotojas pateikia užsakymą (Frontend aplikacija): Vartotojas Tokijuje pateikia užsakymą. Frontend aplikacija siunčia HTTP užklausą į „Užsakymų paslaugą“ (greičiausiai Python mikroservisas).
- Užsakymų paslauga sukuria užsakymą: „Užsakymų paslauga“ patvirtina užklausą, sukuria naują užsakymą savo duomenų bazėje ir publikuoja
OrderCreatedįvykį į „Kafka“ temą pavadinimuorders.Python kodo fragmentas (užsakymų paslauga):
from confluent_kafka import Producer p = Producer({'bootstrap.servers': 'kafka-broker-address'}) def delivery_report(err, msg): if err is not None: print(f"Message delivery failed: {err}") else: print(f"Message delivered to {msg.topic()} [{msg.partition()}] @ {msg.offset()}") def publish_order_created(order_data): message_json = json.dumps(order_data) p.produce('orders', key=str(order_data['order_id']), value=message_json, callback=delivery_report) p.poll(0) # Trigger delivery reports print(f"Published OrderCreated event for order {order_data['order_id']}") # Assuming order_data is a dict like {'order_id': 12345, 'user_id': 987, 'items': [...], 'total': 150.00, 'currency': 'JPY', 'shipping_address': {...}} # publish_order_created(order_data) - Atsargų paslauga atnaujina atsargas: „Atsargų paslauga“ (taip pat Python, vartojanti iš
orderstemos) gaunaOrderCreatedįvykį. Ji patikrina, ar prekės yra sandėlyje, ir publikuojaInventoryUpdatedįvykį.Python kodo fragmentas (atsargų vartotojas):
from confluent_kafka import Consumer, KafkaException import json c = Consumer({ 'bootstrap.servers': 'kafka-broker-address', 'group.id': 'inventory_group', 'auto.offset.reset': 'earliest', }) c.subscribe(['orders']) def process_order_created_for_inventory(order_event): print(f"Inventory Service: Processing OrderCreated event for order {order_event['order_id']}") # Logic to check stock and reserve items # Publish InventoryUpdated event or handle insufficient stock scenario print(f"Inventory Service: Stock updated for order {order_event['order_id']}") while True: msg = c.poll(1.0) if msg is None: continue if msg.error(): if msg.error().code() == KafkaException._PARTITION_EOF: # End of partition event, not an error print('%% Aborted') break elif msg.error(): raise msg.error() else: try: order_data = json.loads(msg.value().decode('utf-8')) process_order_created_for_inventory(order_data) except Exception as e: print(f"Error processing message: {e}") c.close() - Mokėjimo paslauga apdoroja mokėjimą: „Mokėjimo paslauga“ (Python) apdoroja
OrderCreatedįvykį. Ji naudoja užsakymo sumą ir valiutą (pvz., JPY), kad inicijuotų mokėjimą per mokėjimo šliuzą. Tada ji publikuojaPaymentProcessedįvykį arbaPaymentFailedįvykį.Pastaba: Paprastumo dėlei kol kas darysime prielaidą, kad mokėjimas pavyko.
- Pristatymo paslauga paruošia siuntą: „Pristatymo paslauga“ (Python) apdoroja
PaymentProcessedįvykį. Ji naudoja pristatymo adresą ir prekes iš originalaus užsakymo (galbūt gautas, jei nebuvo pilnai įvykyje), kad paruoštų siuntą. Ji publikuojaShipmentPreparedįvykį.Tarptautinis pristatymas apima sudėtingumus, tokius kaip muitinės formos ir vežėjo pasirinkimas, kurie būtų „Pristatymo paslaugos“ logikos dalis.
- Pranešimų paslauga informuoja vartotoją: „Pranešimų paslauga“ (Python) apdoroja
ShipmentPreparedįvykį. Ji suformuoja pranešimo žinutę (pvz., „Jūsų užsakymas #{order_id} išsiųstas!“) ir išsiunčia ją vartotojui el. paštu arba tiesioginiu pranešimu, atsižvelgdama į vartotojo regioną ir pageidaujamą kalbą.
Šis paprastas srautas iliustruoja, kaip pranešimais pagrįstas ryšys ir EDA leidžia skirtingoms sistemos dalims dirbti kartu asinchroniškai, nepriklausomai ir reaktyviai.
Išvada
Įvykiais valdoma architektūra, varoma patikimu pranešimais pagrįstu ryšiu, siūlo patrauklų požiūrį į modernių, sudėtingų programinės įrangos sistemų kūrimą. Python, su savo turtinga bibliotekų ekosistema ir būdingu asinchroninio programavimo palaikymu, yra išskirtinai gerai tinkama EDA diegimui.
Įsisavinę tokias sąvokas kaip pranešimų tarpininkai, asinchroniniai modeliai ir gerai apibrėžti projektavimo modeliai, galite kurti programas, kurios yra:
- Atsietos: Paslaugos veikia nepriklausomai, mažinant tarpusavio priklausomybes.
- Keičiamos: Atskirus komponentus galima keisti atsižvelgiant į poreikį.
- Atsparios: Gedimai yra izoliuoti, o sistemos gali atsigauti sklandžiau.
- Reaguojančios: Programos gali greitai reaguoti į realaus laiko pokyčius.
Kai pradėsite kurti savo įvykiais valdomas sistemas su Python, nepamirškite teikti pirmenybės aiškiam įvykių schemos kūrimui, patikimam klaidų tvarkymui, išsamiam stebėjimui ir atidžiam požiūriui į pasaulinius aspektus. Kelionė į EDA yra nuolatinio mokymosi ir prisitaikymo kelias, tačiau sistemos patikimumo ir lankstumo atžvilgiu atlygis yra didelis.
Pasiruošę kurti savo kitą keičiamą programą? Ištyrinėkite Python pranešimų eilių bibliotekas ir pradėkite kurti savo įvykiais valdomą ateitį šiandien!