Skip to content
Language:hu Author:Laborci Gergely
messaging

Nyugtázás, kézbesítési garanciák és duplikáció

Célok

A lecke végére meg tudod különböztetni a producer- és a consumer-nyugtát, el tudod magyarázni az at-most-once, at-least-once és exactly-once garanciát, és meg tudod mondani, miért kell a fogyasztónak számítania duplikációra.

Miért kell?

Az üzenetküldés megbízhatóságát a teljes útvonalon kell értelmezni: termelő, közvetítő, fogyasztó és üzleti adattároló. A „megbízható közvetítő” nem jelenti, hogy egy üzleti hatás pontosan egyszer következik be.

Két külön nyugta

A RabbitMQ dokumentációja szerint a publisher confirm (termelői nyugta) azt közli a termelővel, hogy a közvetítő kezelte az üzenetet (tartós sornál ez azt jelenti, hogy lemezre írta). A consumer acknowledgement (fogyasztói nyugta) a fogyasztó feldolgozásához kapcsolódik. Az automatikus nyugtázási módot a dokumentáció „nem biztonságosnak” tartja megbízható kézbesítést igénylő munkáknál: ilyenkor az üzenet a kiküldéskor már kézbesítettnek számít. Kézi nyugtázásnál a nem nyugtázott üzenet a csatorna vagy kapcsolat lezárásakor automatikusan visszakerül a sorba.

sequenceDiagram
  participant P as Termelő
  participant B as Közvetítő
  participant C as Fogyasztó
  participant D as Üzleti adatbázis
  P->>B: Üzenet
  B-->>P: Termelői nyugta
  B->>C: Kézbesítés
  C->>D: Üzleti módosítás
  D-->>C: Commit
  C-->>B: Fogyasztói nyugta

Ha a fogyasztó a commit után, de a nyugta előtt áll le, az üzenet újra kézbesülhet, miközben a hatás már megtörtént. Ha a nyugta a commit előtt megy ki, a kiesés után a munka elveszhet. A nyugtázás sorrendje tehát a tartóssági terv része.

At-most-once, at-least-once, exactly-once

  • At-most-once (legfeljebb egyszer): nincs újrakézbesítés, ezért az üzenet elveszhet. Gyorsan elavuló adatnál (például egy mérőműszer legfrissebb értéke) elfogadható.
  • At-least-once (legalább egyszer): újrakézbesítés történik a sikerig, ezért duplikáció lehetséges. Az Amazon SQS standard sorai például legalább egyszeri kézbesítést adnak, előfordulhat, hogy egy üzenetből több példány is kézbesül, és az üzenetek ritkán sorrenden kívül érkezhetnek; a RabbitMQ dokumentációja is azt kéri, hogy a fogyasztók készüljenek újrakézbesítésre és idempotensek legyenek.
  • Exactly-once (pontosan egyszer): egy közvetítő vagy feldolgozó adott tranzakciós körön belül adhat ilyen tulajdonságot, de egy külső e-mail, banki API vagy másik adatbázis hatása ettől még nem lesz pontosan egyszeri. Az állítás határát mindig meg kell nevezni.

Idempotens fogyasztó

Az at-least-once kézbesítés idempotens fogyasztóval együtt használható biztonságosan (6.5). A fogyasztó tartósan rögzítheti a feldolgozott eseményazonosítót az üzleti módosítással egy tranzakcióban (inbox, 5.3), így újrakézbesítéskor felismeri a már megtörtént hatást. Az ellenőrzés és a mentés ne két független lépés legyen, mert két párhuzamos fogyasztó mindkettőt „újnak” láthatja. A deduplikációs azonosítók megőrzési ideje legyen összhangban az ismétlés időablakával, különben egy késői ismétlés új műveletnek látszik. Az azonosítóhoz tartozhat a tartalom lenyomata is.

Jellemzők (garanciák szerint)

Szempont At-most-once At-least-once „Exactly-once”
Veszhet-e el? Igen Nem (a megállapodott feltételekkel) Nem, a körön belül
Ismétlődhet-e? Nem Igen Nem, a körön belül
Mit kér a fogyasztótól? Elfogadja a veszteséget Idempotencia A kör határának ismerete
Mikor jó? Gyorsan elavuló adat Üzleti parancs, értesítés Szűk, zárt rendszerek tranzakciós köre

Gyakori tévhitek

Állítás Pontosítás
„A megbízható közvetítővel nem lesz duplikáció.” Újrakézbesítés mellett igen.
„Az exactly-once mindent pontosan egyszer hajt végre.” Csak a megnevezett körön belül.
„A termelői nyugta azt jelenti, hogy feldolgozták.” Csak azt, hogy a közvetítő kezelte.
„A nyugta mindig a feldolgozás előtt jó.” Kiesésnél a munka elveszhet.

Röviden

  • A termelői és a fogyasztói nyugta külön esemény.
  • At-least-once esetén a fogyasztó idempotens legyen.
  • Az exactly-once csak megnevezett határon belül igaz.
  • A deduplikációs azonosítót az üzleti módosítással egy tranzakcióban kell rögzíteni.

Ellenőrző kérdések

  1. Miért érkezhet ismételt üzenet sikeres adatbázis-commit után?
  2. Hol legyen a deduplikációs rekord tranzakciós határa?
  3. Miért nem bizonyít egy közvetítő exactly-once funkciója pontosan egyszer elküldött e-mailt?

Források

Prerequisites (3)

  • message queue
  • idempotencia
  • transactional outbox

Teaches (2)

  • nyugtázás
  • kézbesítési garanciák