Kéznélküli levelek sorai vs. memórián belüli újrapróbálkozások
A kézbesítetlen levelek sorai és a memórián belüli újrapróbálkozások két alapvetően eltérő megközelítést képviselnek az üzenetfeldolgozási hibák kezelésében elosztott rendszerekben: a DLQ-k tartósan elkülönítik a problémás üzeneteket, míg a memórián belüli újrapróbálkozások könnyűsúlyú, alacsony késleltetésű helyreállítást kínálnak a perzisztencia terhelése nélkül.
Kiemelt tartalmak
kézbesítetlen levelek sorai határozatlan ideig megőrzik a sikertelen üzeneteket, így elengedhetetlenek az audit és a megfelelőségi forgatókönyvekhez.
A memórián belüli újrapróbálkozások mikroszekundumos szintű többletterheléssel futnak, szemben a sorműveletek milliszekundumos több mint késleltetésével.
A DLQ-k lehetővé teszik a különálló operatív csapatok számára a hibák kezelését alkalmazáskód-módosítások telepítése nélkül.
A memórián belüli megközelítésekből származó újrapróbálkozási viharok kaszkádos hibákat okozhatnak, ha nincsenek áramkör-megszakítók korlátozva
Mi az a Kéznélküli levelek sorai?
Állandó üzenetsorok, amelyek rögzítik a sikertelen üzeneteket későbbi ellenőrzés és újrafeldolgozás céljából.
Az üzenetek a maximális újrapróbálkozási küszöbérték túllépése után átkerültek a DLQ-ba, megőrizve az üzenet teljes tartalmát és metaadatait.
Eredetileg olyan vállalati üzenetküldő rendszerek népszerűsítették, mint az IBM MQ és a JMS, ma már szabvány az AWS SQS-ben, az Azure Service Bus-ban és a RabbitMQ-ban.
Lehetővé teszi a leválasztott hibaelemzést a fő feldolgozási folyamatok blokkolása nélkül, lehetővé téve a csapatok számára a problémák megoldását és az üzenetek visszajátszását
Általában integrálódnak a monitorozó és riasztórendszerekkel, hogy értesítsék az operátorokat, amikor az üzenetek kézbesítetlen állapotba kerülnek.
Időalapú lejárati szabályzatok támogatása, az AWS SQS DLQ-k alapértelmezés szerint akár 14 napig is megőrzik az üzeneteket.
Mi az a Memórián belüli újrapróbálkozások?
Azonnali újrapróbálkozási logika végrehajtása ugyanazon a folyamaton belül, külső üzenetmegőrzés nélkül.
Az újrapróbálkozási szabályzatok általában exponenciális visszatartást alkalmaznak, ahol a késleltetések megduplázódnak a kísérletek között (pl. 1, 2, 4, 8).
Az olyan keretrendszerek, mint a Polly (.NET), a Resilience4j (Java) és a Retry (Python), konfigurálható újrapróbálkozási stratégiákat biztosítanak áramkör-megszakító mintákkal.
Ne használjon további infrastrukturális erőforrásokat a feldolgozó alkalmazás meglévő memóriáján és CPU-ján túl.
Teljes hiba, ha az alkalmazás összeomlik az újrapróbálkozás közben, elveszítve az újrapróbálkozási állapotot és potenciálisan az eredeti műveleti kontextust.
Leginkább átmeneti hibákhoz, például hálózati akadozásokhoz, adatbázis-kapcsolati időtúllépésekhez és ideiglenes szolgáltatáskimaradásokhoz alkalmas.
Összehasonlító táblázat
Funkció
Kéznélküli levelek sorai
Memórián belüli újrapróbálkozások
Kitartás
Tartós üzenettárolás külön sorban
Efemer, csak az alkalmazás memóriájában él
Hibaelhárítás
Túléli az alkalmazás összeomlását és újraindítását
Elveszett, ha a folyamat leáll az újrapróbálkozás során
Infrastruktúra költsége
További sortárolási és átviteli költségek
Nincs további infrastruktúra az alkalmazáson túl
Működési láthatóság
Beépített mérőszámok, riasztások és visszajátszási lehetőségek
Egyéni naplózást és monitorozást igényel
A késleltetés hatása
Nagyobb késleltetés a sorműveletek miatt
Minimális késleltetés, azonnali újrapróbálkozás
Használati eset illeszkedése
Kritikus munkafolyamatok, amelyek garantált feldolgozást igényelnek
Nem kritikus műveletek átmeneti hibákkal
Üzenetsorrend
Megőrizheti vagy megzavarhatja az eredeti sorrendet
Természetes módon fenntartja a folyamat közbeni sorrendet
Csapatmunka
Lehetővé teszi a javítás és a visszajátszás külön csapattulajdonlását
Szorosan összekapcsolva az alkalmazástelepítéssel
Részletes összehasonlítás
Megbízhatósági és tartóssági garanciák
A kézbesítetlen levelek sorai akkor remekelnek, ha egyáltalán nem veszíthetsz el üzeneteket. Amint egy üzenet megérkezik egy DLQ-ba, ott is marad, amíg valaki explicit módon nem foglalkozik vele, még akkor is, ha a teljes szolgáltatás újraindul. Ezzel szemben a memóriában lévő újrapróbálkozások a levegőbe olvadnak, ha a pod összeomlik, vagy a folyamat leáll a telepítés során. Ez teszi a DLQ-kat kézenfekvő választássá pénzügyi tranzakciókhoz, készletfrissítésekhez vagy bármilyen megfelelőséggel kapcsolatos feladathoz.
Teljesítmény- és késleltetési jellemzők
memórián belüli újrapróbálkozások kétségtelenül gyorsak. Nincs hálózati ugrás, nincs sor API-hívás, nincs szerializálási terhelés, csak egy gyors alvás és újrapróbálkozás. Nagy áteresztőképességű rendszereknél, amelyek másodpercenként több ezer üzenetet dolgoznak fel, ez a különbség összeadódik. A DLQ-k mérhető késleltetést okoznak, különösen akkor, ha az üzeneteknek át kell haladniuk a hálózati határokon, hogy elérjék a különálló sorszolgáltatást. Egyes csapatok hibridizálnak, memórián belüli újrapróbálkozásokat használnak a gyors átmeneti javításokhoz, és DLQ-kat végső biztonsági hálóként.
Működési komplexitás és hibakeresés
A DLQ-k egyértelmű működési határokat hoznak létre. Az ügyeletes mérnököt értesítik, megvizsgálja a kézbesítetlen levelek várólistáját, kijavítja a mögöttes hibát, és visszajátssza az üzeneteket. Ez egy jól érthető munkafolyamat. A memórián belüli újrapróbálkozások eltemetik a hibákat az alkalmazásnaplókban, ami gyakran naplóösszesítést és egyéni irányítópultokat igényel ahhoz, hogy egyáltalán tudjuk, mi történik az újrapróbálkozásokkal. Amikor az újrapróbálkozások kimerülnek, a hibafeloldók rémálma, különösen a mikroszolgáltatásokban, ahol a hiba a későbbiekben is továbbterjedhet, mielőtt bárki észrevenné.
Költségmegfontolások méretarányosan
A felhőalapú várólista-szolgáltatások kérésenként és tárolt üzenetenként számláznak. Egy forgalmas, több millió üzenettel rendelkező DLQ nem triviálisan befolyásolhatja a számlát, különösen, ha a megőrzési szabályzatok nagylelkűek. A memórián belüli újrapróbálkozások lényegében ingyenesek az infrastruktúra szempontjából, bár memóriát fogyasztanak, és más szálakat kiéheztethetnek, ha az újrapróbálkozási viharok nincsenek korlátozva. A költségérzékeny induló vállalkozások esetében ez gyakran a memórián belüli megközelítések felé billenti a mérleget, amíg a bevétel nem indokolja a megbízhatósági prémiumot.
Integráció a modern architektúrákkal
Az eseményvezérelt architektúrák és a szerver nélküli függvények minden eddiginél relevánsabbá tették a DLQ-kat. Az AWS Lambda, az Azure Functions és a Google Cloud Functions mind natívan támogatják a kézbesítetlen betűk konfigurációit. A memórián belüli újrapróbálkozások természetesebben illeszkednek a hagyományos alkalmazásszerverekbe és a hosszan futó folyamatokba. A Kubernetes és az efemer számítás térnyerése valójában bonyolulttá tette a memórián belüli stratégiákat, a konténerek kevés figyelmeztetéssel leállíthatók, így a DLQ-k egyre vonzóbbak még azoknak a csapatoknak is, amelyek korábban kerülték őket.
Előnyök és hátrányok
Kéznélküli levelek sorai
Előnyök
+Garantált üzenettartósság
+Tiszta működési átadás
+Natív felhőintegráció
+Támogatja a visszajátszást és az auditálást
+Elkülöníti a meghibásodás hatását
Tartalom
−További infrastrukturális költségek
−Magasabb végponttól végpontig tartó késleltetés
−Visszajátszási mechanizmust igényel
−Elavult üzeneteket halmozhat fel
−Komplexebb architektúra
Memórián belüli újrapróbálkozások
Előnyök
+Rendkívül alacsony késleltetés
+Nincs extra infrastruktúra
+Egyszerűen megvalósítható kezdetben
+Minimális működési költségek
+Gyors hibajelzés
Tartalom
−Elveszett a folyamat összeomlása miatt
−Elrejtve a műveletek elől
−Újrapróbálkozási viharokat okozhat
−Szoros csatolás az alkalmazás életciklusához
−Nehezebb utólag hibakeresni
Gyakori tévhitek
Mítosz
A kézbesítetlen levelek sorai kiküszöbölik az alkalmazásokban az újrapróbálkozási logika szükségességét.
Valóság
A DLQ-k a célállomások az újrapróbálkozások kimerülése után, nem pedig az újrapróbálkozási logika helyettesítője. A legtöbb implementáció továbbra is azonnali vagy késleltetett újrapróbálkozásokat hajt végre, mielőtt egy üzenetet halottnak tekintene. Köztes újrapróbálkozások nélkül minden átmeneti hiba azonnal elárasztaná a DLQ-t.
Mítosz
A memórián belüli újrapróbálkozások mindig gyorsabbak, és ezért jobbak a teljesítmény szempontjából.
Valóság
Míg az egyes újrapróbálkozások gyorsabbak, a korlátlan memórián belüli újrapróbálkozások telíthetik a szálkészleteket és ronthatják a rendszer teljes átviteli sebességét. A teljesítménybeli előny gyorsan eltűnik, amikor az újrapróbálkozási viharok megszakítókat váltanak ki, vagy túlterhelik a downstream szolgáltatásokat.
Mítosz
A kézbesítetlen levelek várólistáján lévő üzenetek később automatikusan feldolgozásra kerülnek.
Valóság
DLQ-k passzív tárolók, semmi sem történik ezekkel az üzenetekkel, amíg kifejezett emberi vagy automatizált beavatkozás nem történik. Sok csapat fedezett fel hónapokkal ezelőtti üzeneteket a DLQ-kban, mivel senki sem építette fel a visszajátszási folyamatot.
Mítosz
Kizárólag a DLQ-k és a memórián belüli újrapróbálkozások között kell választania.
Valóság
Ezek a minták gyönyörűen kiegészítik egymást. A legellenállóbb rendszerek a memórián belüli újrapróbálkozásokat exponenciális visszalépéssel használják a gyors helyreállítás érdekében, majd egy ésszerű küszöbérték után DLQ-kra eszkalálódnak. Ez a rétegzett megközelítés mind az átmeneti, mind az állandó hibamódokat lefedi.
Mítosz
A memórián belüli újrapróbálkozások nem alkalmasak elosztott rendszerek esetén.
Valóság
Bár kevésbé robusztusak, mint a DLQ-k, a memórián belüli újrapróbálkozások továbbra is gyakoriak és megfelelőek az elosztott rendszerekben idempotens, nem kritikus műveletekhez. A kulcs az újrapróbálkozási stratégia összehangolása a hiba tényleges üzleti következményével, és nem az egyetlen minta mindenkire illeszkedő feltételezése.
Mítosz
A kézbesítetlen levelek sorai megakadályozzák az üzenetek elvesztését rendszerkiesések esetén.
Valóság
DLQ-k csak azoknál az üzeneteknél segítenek, amelyeket a sorkezelő rendszer már elfogadott. Ha az üzenet hálózati partíció vagy a létrehozó hibája miatt soha nem éri el az elsődleges várólistát, a DLQ nem tudja varázsütésre helyreállítani. A teljes körű megbízhatósághoz a létrehozói oldali perzisztencia is szükséges.
Gyakran Ismételt Kérdések
Mi okozza pontosan azt, hogy egy üzenet a kézbesítetlen levelek várólistájára kerül?
Az üzenetek jellemzően a beállított újrapróbálkozási kísérletek kimerítése után kerülnek be egy DLQ-ba, ami azt jelentheti, hogy túllépik az SQS-ben a fogadások maximális számát, több felhasználón keresztüli kézbesítés sikertelen, vagy az alkalmazáskód explicit módon elutasítja őket. A pontos trigger platformonként változik: az AWS SQS egy újraindítási szabályzatot használ, amely meghatározza a fogadások maximális számát, míg az Azure Service Bus nyomon követi a kézbesítések számát. Amint átlépi ezt a küszöbértéket, az üzenetküldési infrastruktúra automatikusan áthelyezi vagy átmásolja az üzenetet a hozzá tartozó kézbesítetlen levelek várólistájába.
Hogyan kezelik a memórián belüli újrapróbálkozások a folyamatok újraindítását vagy összeomlását?
Nem teszik, ami az alapvető korlátjuk. Bármely újrapróbálkozási állapot kizárólag a futó folyamat heap-jében létezik. Ha az alkalmazás összeomlik, telepítés közben leáll, vagy a konténer átütemezésre kerül, az összes függőben lévő újrapróbálkozás és azok kontextusa eltűnik. Azokhoz a műveletekhez, amelyeknek túl kell élniük az ilyen eseményeket, állandó újrapróbálkozási mechanizmusokra van szükség, legyen az DLQ, adatbázis-alapú feladatsor, vagy elosztott feladatrendszerek, mint például a Celery vagy a Hangfire.
Kombinálhatók a kézbesítetlen levelek várakozási sorai a memórián belüli újrapróbálkozásokkal ugyanazon a rendszeren belül?
Abszolút, és ez valójában sok csapat számára a legjobb gyakorlat. A tipikus minta a memórián belüli újrapróbálkozásokat foglalja magában exponenciális visszaállítással az azonnali átmeneti helyreállítás érdekében, mondjuk három próbálkozás néhány másodperc alatt. Ha ezek sikertelenek, az üzenet vagy művelet közzé lesz téve egy DLQ-támogatással rendelkező várólistában a tartós kezelés érdekében. Ez biztosítja a memórián belüli újrapróbálkozások sebességét a hibajelzések esetén, és a DLQ-k biztonságát az állandó problémák esetén.
Milyen monitorozást kell beállítani a kézbesítetlen levelek soraihoz?
Legalább a várólista mélységére, a legrégebbi üzenet korára és a bejövő üzenetek arányára vonatkozó riasztásokat kell konfigurálni. A DLQ érkezések hirtelen megugrása általában egy telepített hibára utal. Az üzenetek korára vonatkozó riasztások olyan eseteket észlelnek, amikor az újrajátszás nem történik meg. Sok csapat a DLQ üzenetek és a sikeresen feldolgozott üzenetek arányát is nyomon követi állapotjelzőként. A CloudWatch, az Azure Monitor vagy a Datadog mind képes ezeket a mérőszámokat megjeleníteni személyhívó integrációval.
Vannak alternatívák a DLQ-kra és a memórián belüli újrapróbálkozásokra?
Számos minta hasonló igényeket elégít ki. A Kimenő üzenetek minta tranzakciósan tárolja az eseményeket az üzleti adatokkal, biztosítva az atomicitást. A Saga minta kompenzáló műveletekkel kezeli a hosszú ideig futó elosztott tranzakciókat. Az adatbázis-alapú jobsorok, mint például a Sidekiq vagy a pg-boss, dedikált üzenetközvetítők nélkül is megőrizik az adatokat. Az eseményforrás egy csak hozzáfűzésre szolgáló naplóból rekonstruálja az állapotot, ami másképp kezeli az újrapróbálkozási szemantikát. A helyes választás a konzisztenciakövetelményektől és a meglévő infrastruktúrától függ.
Hogyan lehet biztonságosan visszajátszani az üzeneteket egy kézbesítetlen levelek sorából?
Soha ne játssza vissza közvetlenül az eredeti várólistára ellenőrzés nélkül, mert ez végtelen ciklusokhoz vezet, ha a kiváltó ok továbbra is fennáll. Ehelyett helyezze a DLQ üzeneteket egy különálló elemzési környezetbe, vizsgálja meg a reprezentatív mintákat a hibaminta azonosítása érdekében, javítsa ki az alapvető problémát, majd szelektíven, kötegekben játssza le újra monitorozással. Az AWS DLQ újraindítási funkciókat biztosít, és az olyan eszközök, mint az Amazon EventBridge Pipes, automatizálhatják a feltételes visszajátszási munkafolyamatokat.
Mitől lesz jó egy újrapróbálkozási szabályzat a memórián belüli újrapróbálkozásokhoz?
Az exponenciális visszatartás jitterrel az aranystandard. Jitter nélkül a több kliens szinkronizált újrapróbálkozásai hatalmas csordaproblémákat okozhatnak a szolgáltatások helyreállításával szemben. Korlátozd a maximális késleltetést a korlátlan várakozások elkerülése érdekében, és mindig állíts be maximális újrapróbálkozások számát. Fontold meg olyan áramkör-megszakítók használatát, amelyek teljesen leállítják az újrapróbálkozásokat, ha a meghibásodási arány meghaladja a küszöbértékeket, így időt adva a downstream szolgáltatásoknak a helyreállításra, ahelyett, hogy leállás közben sürgetnék őket.
A kiszolgáló nélküli függvények jól működnek a memórián belüli újrapróbálkozásokkal?
Nem különösebben. A Lambda és a hasonló függvények állapot nélküliek és rövid életűek. A tizenöt perces maximális végrehajtási idő azt jelenti, hogy a memórián belüli újrapróbálkozási ablak korlátozott. Ami még fontosabb, ha a Lambda meghibásodik, a teljes végrehajtási kontextus eltűnik. A szerver nélküli architektúrák erősen előnyben részesítik a külső állapotokat, így a DLQ-k vagy a beépített újrapróbálkozási logikával rendelkező lépésfüggvények sokkal természetesebb illeszkedést biztosítanak, mint a memórián belüli megközelítések.
Miben különböznek az üzenetek sorrendjének meghatározása a két megközelítés között?
DLQ-k bonyolíthatják a rendezési garanciákat. Ha az elsődleges várólistád FIFO, az üzenetek DLQ-ba és DLQ-ból történő mozgatása megzavarhatja a sorrendet, kivéve, ha a platform kifejezetten megőrzi a sorrendet. Az egyetlen felhasználón belüli memórián belüli újrapróbálkozások természetesen fenntartják az adott felhasználó üzeneteinek sorrendjét, bár több felhasználó továbbra is párhuzamosan dolgozza fel az üzeneteket. Egyes rendszerek sorszámokat vagy alkalmazásszintű sorrendet használnak a megfelelő sorrend rekonstruálására az újrapróbálkozási mechanizmus után.
Milyen biztonsági szempontok vonatkoznak a kézbesítetlen levelek soraira?
A DLQ-k ugyanazokat a bizalmas adatokat tartalmazzák, mint az elsődleges várólisták, néha többet is, mivel hibakontextust tartalmaznak. Alkalmazzon azonos titkosítást, hozzáférés-vezérlést és naplózást. Legyen óvatos a visszajátszási mechanizmusokkal, a régi üzenetek újrafeldolgozása váratlan mellékhatásokat válthat ki, ha a downstream rendszerek nem idempotensek. Egyes szabályozott iparágak explicit jóváhagyási munkafolyamatokat igényelnek, mielőtt a DLQ-üzenetekhez hozzá lehetne férni vagy újra le lehetne játszani.
Mikor kell teljesen elkerülni a memórián belüli újrapróbálkozásokat?
Hagyd ki őket, ha a feldolgozásnak olyan mellékhatásai vannak, amelyek nem idempotensek, például egy hitelkártya kétszeri terhelése egy újrapróbálkozás miatt katasztrofális. Kerüld el őket, ha a pontos egyszeri szemantika számít, és hiányzik a deduplikáció. Ne hagyatkozz rájuk hosszú ideig futó műveletek esetén, ahol a folyamat esetleg nem él elég sokáig az újrapróbálkozások befejezéséhez. És ne használd őket, ha az operatív csapatoknak betekintést kell látniuk a hibamintázatokba kódmódosítások telepítése nélkül.
Hogyan viszonyulnak a költségek vállalati szinten?
Egy tipikus AWS rendszer SQS szabványos várólistákkal és DLQ-kkal akár néhány dollárt is elkölthet millió üzenetenként, plusz a megőrzött üzenetek tárhelyét. Egy havi milliárdokat feldolgozó rendszer esetében ez jelentős költség. A memórián belüli újrapróbálkozások a számítási költségeket áthárítják a rendszerre, amelyet már amúgy is fizet. Az újrapróbálkozási viharok azonban megnövelhetik a CPU- és memóriaigényt, ami potenciálisan nagyobb példányméretet igényelhet. A legtöbb teljes birtoklási költség elemzés a memórián belüli megoldást részesíti előnyben az alacsony kritikusságú, nagy volumenű munkákhoz, és a DLQ-kat az alacsonyabb volumenű, alapvető munkafolyamatokhoz.
Ítélet
Válassza a kézbesítetlen levelek sorát, ha az üzenetvesztés elfogadhatatlan, és az operatív csapatoknak egyértelmű hibahatárokat kell kezelniük. Válassza a memórián belüli újrapróbálkozásokat, ha a sebesség a legfontosabb, az infrastruktúra egyszerűsége az elsődleges, és a hibák valóban átmenetiek, nem pedig szisztémásak. Sok fejlett rendszer valójában mindkettőt kombinálja, memórián belüli újrapróbálkozásokat használva az azonnali helyreállításhoz, és DLQ-kat végső biztonsági megoldásként.