Zprávy v architektuře orientované na služby

(Joan Zapata) (8. prosince 2020)

Architektura orientovaná na služby (SOA) se osvědčila jeho silné stránky prakticky ve všech průmyslových odvětvích k výrobě škálovatelných a evolučních systémů. SOA má mnoho významů, ale její základní myšlenka rozdělení komplexní aplikace na menší, opakovaně použitelné a volně spojené služby prošla od konce 90. let dlouhou cestou. Koncept jsme přijali od prvního dne a po třech letech nyní máme zhruba dvacet oddělených služeb založených na doménách, které strukturují naše backendové aplikace. Umožnilo nám to používat jazyky, které se nám líbily – jako Kotlin , Elixir – a nástroje chtěli jsme – jako Event Sourcing – pro daný úkol.

Ale mít více služeb má své vlastní výzvy, první je jak zajistit, aby služby vzájemně komunikovaly ? Existuje spousta strategií a tento článek přináší návratnost zkušeností s těmi, které používáme v Memo Bank.

Začněme dvěma službami a tímto jednoduchým příkladem použití:

REST přes HTTPS

Jako mnoho backendových aplikací jsme začali s REST voláními přes HTTPS.

Cyklické závislosti mezi službami je třeba se za každou cenu vyhnout, takže smlouvy nemůže přímo říci zákazníkům , aby aktivovali nového zákazníka ihned po podpisu smlouvy. Místo toho musí zákazníci pravidelně odesílat žádosti o smlouvy , aby věděli, kdy je úkol hotový.

HTTPS je skvělý začátek a určitě je třeba si jej ponechat v sadě nástrojů: jeho nastavení je jednoduché, široce podporované a také se používá k vystavení API frontendovým aplikacím. Ale toto schéma má jeden velký problém, je to synchronní (i když to nemusí nutně blokovat). To znamená, že zatímco smlouvy fungují, zákazníci čekají s aktivním připojením. Při použití ve velkém měřítku to znamená, že nejpomalejší služba může zpomalit celý systém. To také znamená, že když služba kontrakty není k dispozici, služba zákazníci také není, což se nazývá kaskádové selhání.

Jak jsme řešili Tento problém? Použili jsme dva různé vzory: diskrétní a nepřetržité zasílání zpráv.

Diskrétní zasílání zpráv

Vezměme si první případ použití: zákazníci chce smlouvy k odeslání smlouvy.

Za tímto účelem můžeme problém vyřešit pomocí mechanismu diskrétních zpráv: fronty . Frontu můžete vidět jako vysoce dostupnou poštovní schránku třetí strany. I když hlavní služba není k dispozici, schránka přijímá zprávy. Více instancí stejné služby může spotřebovat stejnou frontu, v takovém případě fronta funguje jako nástroj pro vyrovnávání zatížení a zajišťuje, že každá zpráva bude zpracována alespoň jednou. Jakmile je zpráva zpracována, poštovní schránka na ni může zapomenout.

Pomocí front odesíláme příkazy (např. „SendContract“) z jedné služby do druhé. Má několik výhod:

  • Služba volajícího se nespoléhá na dostupnost přijímající službu a může pokračovat v práci, jakmile je příkaz ve frontě;
  • Přijímač může zpracovávat příkazy vlastním tempem a můžeme snadno škálovat službu přijímače nahoru nebo dolů v závislosti na zatížení jejích front;
  • jako bonus, selhání lze snadno izolovat a řešit ručně (doufáme, že se tématu fronty nedoručených zpráv budeme věnovat v jiném článku).

Průběžné zasílání zpráv

Podívejme se nyní na druhý případ použití, když je podepsána smlouva, smlouvy je třeba informovat zákazníky došlo k tomu, aby to mohlo aktivovat zákazníka.

Je lákavé použít zde jinou frontu, ale jak jsme řekli dříve, nechceme cyklickou závislost, takže smlouvy neví cokoliv o zákaznících . Nemůže tedy odeslat příkaz „ActivateCustomer“ a nemůže vědět, kdy a kam má tento příkaz odeslat.

Tento problém jsme vyřešili pomocí mechanismu nepřetržitého zasílání zpráv: streamy .Stream můžete vidět jako seřazenou posloupnost událostí, které lze spotřebovat v reálném čase, ale jsou také časem k dispozici. Na rozdíl od front, které nesouvisí s prchavými příkazy, proudy vyprávějí přetrvávající příběh .

Každá služba v Memo Bank vysílá proud events popisující životní cyklus jeho zdrojů. Vytváření a udržování těchto událostí je nedílnou součástí každého vývoje , ať už je tato událost okamžitě nutná. Je to součást rutiny, stejně jako automatizované testy a metriky.

Tyto události se tak stávají spolehlivým časově označeným protokolem neměnné fakta . A protože jsou součástí API vysílající služby, mohou být spotřebovány jakoukoli jinou službou, a to jak v reálném čase (po jednom), tak i v budoucnu. Tyto události mají nesmírnou hodnotu pro sledovatelnost a analýzu dat .

Shrnutí:

  • Fronty slouží k odeslání příkazů konkrétní služba;
  • proudy se používají k odhalení faktů z konkrétní služba.

Vše o závislostech

Výše ​​uvedený diagram vás může přimět k tomu, abyste se při pohledu na šipky divili, nezavádí cyklická závislost mezi zákazníky a kontrakty?

Ne to není. Závislost není definována směrem dat, ale znalostními službami se navzájem mají. Zde zákazníci vědí o kontraktech, řekne jí, co má dělat, a naslouchá svému příběhu. Smlouvy ale o zákaznících nic neví, nemusí vědět, kdo příkazy odesílá, ani kdo poslouchá jeho příběh.

Oba fronta a stream jsou součástí smlouvy API a zákazníci závisí na tomto API.

Pojmenování konvence pro příkazy a fakta je pro vyjádření této myšlenky velmi důležitá. Vždy používáme základní formulář pro příkazy, například „SendContract“, a minulý příčestní formulář pro fakta, jako je „ContractSent“.

Všimněte si, že se pohodlně shoduje s naší architekturou Core Banking System založené na CQRS / ES . V této terminologii jsou příkazy stejné a události jsou fakta.

Jak zvolit směr závislosti

Vzhledem k výše vysvětleným principům by toto řešení bylo stejně platné:

Ale pokud jsou obě řešení platná, jak si vybrat jedno nad druhým? No, je to na vás.

Všechno spadá do směru závislosti , kterou chcete nastavit.

A: zákazníci závisí na kontraktech . B: smlouvy závisí na zákaznících .

Zde je několik otázek, které si obvykle klademe:

  • Může být jedna služba snadno agnostická vůči ostatním?
    Zde například za předpokladu, že poskytneme obsah smlouvám , smlouvy mohou být naprosto agnostické ohledně toho, která služba je používá. Je těžší si představit, že zákazníci jsou agnostičtí ohledně skutečnosti, že to vyžaduje smlouvu. Je to ve prospěch A.
  • Co kdyby jedna služba byla třetí stranou?
    Pro například by nemělo smysl, aby Memo Bank outsourcovala zákazníky , ale mohla by to pro smlouvy . Proto je to také ve prospěch A.
  • Je jedna služba organizována jinými službami?
    Implicitní orchestrace je špatná, více o ní najdete v této přednášce Bernda Rueckera. Vytvoření zákazníka je komplexní pracovní postup , který zahrnuje mnoho služeb (odesílání e-mailů, oznámení, vytvoření bankovního účtu atd.), Takže zákazníci je zde pravděpodobně orchestrátor.Díky tomu, že orchestrátor závisí na jiných službách – a ne naopak – je kód mnohem srozumitelnější, protože celý pracovní postup najdete na jednom místě. Je to také ve prospěch A.
  • Vytváří to cyklus v celkové architektuře?
    I když mezi oběma službami neexistuje žádná vazba, obě závisí na jiných službách. Řekněme, že zákazníci závisí na uživatelů a uživatelé závisí na smlouvách již. Pokud bychom zvolili řešení B, vytvořilo by to cyklus se třemi službami. To je také ve prospěch A.

Závěr

Zasílání zpráv je jednou z prvních otázek, na které musíme odpovědět při vytváření architektury orientované na služby. Používání HTTPS a REST se zpočátku zdá jako nejpřímější řešení, ale má svá omezení. Náš arzenál jsme doplnili o fronty a streamy a stanovili jsme hlavně dvě pokyny.

Nejprve by každá služba měla streamovat události když se v rámci této služby vyskytnou fakta, i když tyto události zatím nepotřebujeme. Tyto události by měly vyprávět příběh o tom, co se ve službě děje, například „ContractSent“, „ContractSigned“. To je skvělé pro sledovatelnost – která je vyžadována jako banka -, ale také pro konsolidaci API každé služby a pro snazší práci se systémem pro všechny týmy.

Zadruhé, je to všechno o závislosti . Závislosti utvářejí systém a cyklické závislosti jsou nepřítelem číslo jedna. Jakmile jsou závislosti správně nastaveny, nástroje pro zasílání zpráv jsou právě tady, aby umožnily tok dat jakýmkoli směrem.

Původně publikováno na https://memo.bank/cs/magazine .

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *