Sprievodca transakciami v mikroslužbách

1. Úvod

V tomto článku sa budeme zaoberať možnosťami implementácie transakcie naprieč mikroslužbami.

Skontrolujeme tiež niektoré alternatívy transakcií v scenári distribuovanej mikroslužby.

2. Vyhýbanie sa transakciám v mikroslužbách

Distribuovaná transakcia je veľmi zložitý proces s množstvom pohyblivých častí, ktoré môžu zlyhať. Tiež, ak tieto časti pracujú na rôznych strojoch alebo dokonca v rôznych dátových centrách, proces vykonania transakcie by sa mohol stať veľmi dlhým a nespoľahlivým.

To by mohlo vážne ovplyvniť dojem používateľa a celkovú šírku pásma systému. Takže jedným z najlepších spôsobov riešenia problému distribuovaných transakcií je vyhnúť sa im úplne.

2.1. Príklad architektúry vyžadujúcej transakcie

Mikroslužba je zvyčajne navrhnutá tak, aby bola samostatná a užitočná sama osebe. Malo by byť schopné vyriešiť niektoré atómové obchodné úlohy.

Ak by sme mohli rozdeliť náš systém v takýchto mikroslužbách, je veľká šanca, že by sme vôbec nemuseli implementovať transakcie medzi nimi.

Uvažujme napríklad o systéme vysielania správ medzi používateľmi.

The používateľ mikroslužba by sa týkala používateľského profilu (vytvorenie nového používateľa, úprava údajov profilu atď.) s nasledujúcou základnou triedou domény:

@Entity verejná trieda Používateľ implementuje Serializable {@Id @GeneratedValue (strategy = GenerationType.AUTO) súkromné ​​dlhé ID; @ Základné súkromné ​​meno reťazca; @ Základné súkromné ​​priezvisko; @Základné súkromné ​​Okamžité lastMessageTime; }

The správa mikroslužba by sa týkala vysielania. Zapuzdruje entitu Správa a všetko okolo toho:

@Entity public class Správa implementuje Serializable {@Id @GeneratedValue (strategy = GenerationType.AUTO) súkromné ​​dlhé ID; @Basic private long userId; @ Základný súkromný obsah reťazca; @Základná súkromná okamžitá správaTimestamp; }

Každá mikroslužba má svoju vlastnú databázu. Všimnite si, že sa neodkazujeme na entitu Používateľ od subjektu Správa, pretože triedy používateľov nie sú prístupné z správa mikroslužba. Na používateľa odkazujeme iba podľa id.

Teraz Používateľ subjekt obsahuje lastMessageTime pole, pretože chceme v jej profile zobraziť informácie o čase poslednej aktivity používateľa.

Ak však chcete používateľke pridať novú správu a aktualizovať ju lastMessageTime, teraz by sme museli implementovať transakciu naprieč mikroslužbami.

2.2. Alternatívny prístup bez transakcií

Môžeme zmeniť našu architektúru mikroslužieb a odstrániť pole lastMessageTime z Používateľ subjekt.

Potom by sme mohli tento čas zobraziť v profile používateľa tak, že vydáme samostatnú žiadosť do mikroslužby správ a nájdeme maximum messageTimestamp hodnota pre všetky správy tohto používateľa.

Pravdepodobne, ak správa mikroslužba je veľmi zaťažená alebo dokonca nefunguje, nebudeme môcť zobraziť čas poslednej správy používateľa v jej profile.

To by však mohlo byť prijateľnejšie ako zlyhanie v spáchaní distribuovanej transakcie na uloženie správy len preto, že mikroslužba používateľa neodpovedala včas.

Existujú samozrejme zložitejšie scenáre, keď musíme implementovať obchodný proces vo viacerých mikroslužbách, a nechceme povoliť nekonzistenciu medzi týmito mikroslužbami.

3. Protokol dvojfázového potvrdenia

Dvojfázový protokol odovzdania (alebo 2PC) je mechanizmus na implementáciu transakcie medzi rôznymi softvérovými komponentmi (viac databáz, fronty správ atď.)

3.1. Architektúra 2PC

Jedným z dôležitých účastníkov distribuovanej transakcie je koordinátor transakcií. Distribuovaná transakcia pozostáva z dvoch krokov:

  • Prípravná fáza - počas tejto fázy sa všetci účastníci transakcie pripravia na spáchanie a informujú koordinátora, že sú pripravení transakciu dokončiť
  • Fáza potvrdenia alebo vrátenia - počas tejto fázy vydá koordinátor transakcie všetkým účastníkom príkaz na potvrdenie alebo vrátenie.

Problém s 2PC je, že je dosť pomalý v porovnaní s časom na prevádzku jednej mikroslužby.

Koordinácia transakcie medzi mikroslužbami, aj keď sú v rovnakej sieti, môže skutočne spomaliť systém, takže tento prístup sa zvyčajne nepoužíva v scenári s vysokým zaťažením.

3.2. Štandard XA

Štandard XA je špecifikácia vykonávania distribuovaných transakcií 2PC cez podporné zdroje. Akýkoľvek aplikačný server kompatibilný s JTA (JBoss, GlassFish atď.) Ho podporuje ihneď po vybalení.

Zdrojmi zúčastňujúcimi sa na distribuovaných transakciách môžu byť napríklad dve databázy dvoch rôznych mikroslužieb.

Aby sa však dal tento mechanizmus využiť, musia sa prostriedky nasadiť na jedinú platformu JTA. To nie je vždy možné pre architektúru mikroslužieb.

3.3. REST-AT štandardný koncept

Ďalším navrhovaným štandardom je REST-AT, ktorý prešiel určitým vývojom zo strany RedHat, ale stále sa nedostal z fázy návrhu. Je však podporovaný aplikačným serverom WildFly ihneď po vybalení.

Tento štandard umožňuje použitie aplikačného servera ako koordinátora transakcií so špecifickým rozhraním REST API na vytváranie a pripájanie k distribuovaným transakciám.

Webové služby RESTful, ktoré sa chcú zúčastniť na dvojfázovej transakcii, musia tiež podporovať konkrétne rozhranie REST API.

Bohužiaľ, na premostenie distribuovanej transakcie na miestne zdroje mikroslužby by sme stále museli buď nasadiť tieto zdroje na jednu platformu JTA, alebo vyriešiť netriviálnu úlohu napísania tohto mosta sami.

4. Prípadná konzistentnosť a kompenzácia

Jedným z najuskutočniteľnejších modelov riešenia konzistencie naprieč mikroslužbami je prípadná konzistencia.

Tento model nevynucuje distribuované transakcie ACID naprieč mikroslužbami. Namiesto toho navrhuje použiť niektoré mechanizmy na zabezpečenie toho, že systém bude niekedy v budúcnosti konzistentný.

4.1. Prípad prípadnej konzistencie

Predpokladajme napríklad, že musíme vyriešiť túto úlohu:

  • zaregistrujte si užívateľský profil
  • urobte nejakú automatizovanú kontrolu na pozadí, či má používateľ skutočne prístup do systému

Druhou úlohou je zabezpečiť napríklad to, aby tomuto používateľovi nebol z nejakých dôvodov zakázaný prístup na naše servery.

Môže to však chvíľu trvať a chceli by sme ho extrahovať do samostatnej mikroslužby. Nebolo by rozumné nechať používateľku tak dlho čakať, aby ste vedeli, že bola úspešne zaregistrovaná.

Jedným zo spôsobov riešenia by bol prístup založený na správach vrátane kompenzácie. Zvážme nasledujúcu architektúru:

  • the používateľ mikroslužba poverená registráciou používateľského profilu
  • the validácia mikroslužba poverená vykonaním kontroly pozadia
  • platforma na zasielanie správ, ktorá podporuje trvalé fronty

Platforma pre zasielanie správ by mohla zabezpečiť, aby boli správy odosielané mikroslužbami trvalé. Potom by boli doručené neskôr, ak prijímač momentálne nie je k dispozícii

4.2. Šťastný scenár

V tejto architektúre by bol šťastný scenár:

  • the používateľ mikroslužba zaregistruje používateľa a uloží informácie o nej do svojej miestnej databázy
  • the používateľ mikroslužba označuje tohto používateľa príznakom. Môže to znamenať, že tento používateľ ešte nebol overený a nemá prístup k celej funkcii systému
  • užívateľovi sa pošle potvrdenie o registrácii s varovaním, že nie všetky funkcie systému sú hneď prístupné
  • the používateľ mikroslužba pošle správu do validácia mikroslužba na vykonanie kontroly pozadia používateľa
  • the validácia mikroslužba spustí kontrolu pozadia a odošle správu do služby používateľ mikroslužba s výsledkami kontroly
    • ak sú výsledky pozitívne, používateľ mikroslužba odblokuje používateľa
    • ak sú výsledky negatívne, používateľ mikroslužba vymaže používateľský účet

Po vykonaní všetkých týchto krokov by mal byť systém v konzistentnom stave. Po určitú dobu sa však používateľská entita javila ako neúplná.

Posledným krokom, keď používateľská mikroslužba odstráni neplatný účet, je fáza kompenzácie.

4.3. Scenáre zlyhania

Teraz zvážime niekoľko scenárov zlyhania:

  • ak validácia mikroslužba nie je prístupná, potom platforma na zasielanie správ so svojou funkciou pretrvávajúcich radov zaisťuje, že: validácia mikroslužba by túto správu dostala niekedy neskôr
  • Predpokladajme, že platforma pre zasielanie správ zlyhá, potom používateľ mikroslužba sa pokúsi správu odoslať znova neskôr, napríklad plánovaným dávkovým spracovaním všetkých používateľov, ktorí ešte neboli overení
  • ak validácia mikroslužba prijme správu, overí používateľa, ale nemôže poslať odpoveď späť kvôli zlyhaniu platformy na zasielanie správ, validácia mikroslužba sa tiež pokúsi správu odoslať neskôr
  • ak sa jedna zo správ stratila alebo došlo k inej poruche, používateľ mikroslužba vyhľadá všetkých neoverených používateľov naplánovaným dávkovým spracovaním a znova pošle žiadosti o overenie

Aj keby boli niektoré zo správ vydané viackrát, nemalo by to vplyv na konzistenciu údajov v databázach mikroslužieb.

Dôkladným zvážením všetkých možných scenárov zlyhania môžeme zabezpečiť, aby náš systém vyhovoval podmienkam prípadnej konzistencie. Zároveň by sme nemuseli riešiť nákladne distribuované transakcie.

Musíme si však uvedomiť, že zabezpečenie prípadnej konzistencie je zložitá úloha. Nemá jednotné riešenie pre všetky prípady.

5. Záver

V tomto článku sme diskutovali o niektorých mechanizmoch implementácie transakcií naprieč mikroslužbami.

Na prvom mieste sme tiež preskúmali niektoré alternatívy uskutočnenia tohto štýlu transakcií.


$config[zx-auto] not found$config[zx-overlay] not found