Hantera fel som kan ta varierande lång tid för återhämtning vid anslutning till en fjärrtjänst eller fjärresurs. Det här mönstret kan förbättra ett programs stabilitet och återhämtning.
Kontext och problem
I en distribuerad miljö kan anrop till fjärrresurser och tjänster misslyckas på grund av tillfälliga fel, till exempel långsamma nätverksanslutningar, tidsgränser eller resurser som överkompenseras eller är tillfälligt otillgängliga. Vanligtvis rättar felen till sig själva efter en kort tid och ett stabilt molnprogram ska vara förberett på att hantera dem genom att använda en strategi som Återförsöksmönster.
Det kan dock också finnas situationer då fel beror på oväntade händelser, och det kan ta mycket längre tid att åtgärda. Felen kan variera i allvarlighetsgrad, från en partiell förlust av anslutning till fullständigt fel i en tjänst. I dessa situationer kan det vara meningslöst för ett program att kontinuerligt försöka utföra en åtgärd som sannolikt inte lyckas, och i stället bör programmet snabbt acceptera att åtgärden har misslyckats och hantera det här felet i enlighet med detta.
Om en tjänst är väldigt trafikerad kan fel i en del av systemet dessutom leda till flera fel följda på varandra. En åtgärd som anropar en tjänst kan till exempel konfigureras för att implementera en tidsgräns och svara med ett felmeddelande om tjänsten inte svarar inom den här perioden. Den här strategin kan dock orsaka att många samtidiga begäranden till samma åtgärd blockeras tills tidsgränsen går ut. Dessa blockerade begäranden kan använda kritiska systemresurser som minne, trådar, databasanslutningar och så vidare. Därför kan dessa resurser bli uttömda, vilket orsakar fel i andra eventuellt orelaterade delar av systemet som behöver använda samma resurser. I sådana fall är det att föredra att åtgärden misslyckas omgående och endast försöker anropa tjänsten om det är troligt att den lyckas. Att ange en kortare tidsgräns kan hjälpa till att lösa det här problemet, men tidsgränsen bör inte vara så kort att åtgärden misslyckas för det mesta, även om begäran till tjänsten så småningom skulle lyckas.
Lösning
Kretsbrytarmönstret kan förhindra att ett program upprepade gånger försöker köra en åtgärd som sannolikt kommer att misslyckas. Gör det möjligt att fortsätta utan att vänta på att felet ska åtgärdas eller slösa CPU-cykler medan den avgör att felet är långvarigt. Mönstret Kretsbrytare gör det också möjligt för ett program att identifiera huruvida felet har åtgärdats. Om problemet verkar ha åtgärdats kan programmet försöka anropa åtgärden.
Syftet med mönstret Kretsbrytare är olikt syftet med Återförsöksmönster. Återförsöksmönster igen gör det möjligt för ett program att försöka utföra en åtgärd igen med en förväntan om att den ska lyckas. Mönstret Kretsbrytare förhindrar att ett program försöker utföra en åtgärd som troligen kommer att misslyckas. Ett program kan kombinera de två mönstren med hjälp av Återförsöksmönster och anropa en åtgärd via en kretsbrytare. Logiken för att försöka igen bör vara känslig för undantag som returneras av kretsbrytaren och överge försök om kretsbrytaren indikerar att felet inte är tillfälligt.
En kretsbrytare fungerar som proxy för åtgärder som kan misslyckas. Proxyn bör övervaka antalet nyligen inträffade fel och använda den här informationen för att avgöra om åtgärden ska kunna fortsätta eller returnera ett undantag omedelbart.
Proxyn kan implementeras som en tillståndsdator med följande tillstånd som efterliknar funktionerna i en elektriska kretsbrytare:
Stängd: ett begärande från programmet dirigeras till åtgärden. Proxyn upprätthåller en uppräkning av antalet senaste fel och om anropet till åtgärden misslyckas ökar proxyn det här antalet. Om antalet senaste fel överskrider ett angivet tröskelvärde inom en viss tidsperiod placeras proxyn i Öppet tillstånd. Nu startar proxyn en timeout-timer och när den här timern upphör att gälla placeras proxyn i tillståndet Halvöppen.
Syftet med timeout-timern är att ge systemet tid att åtgärda problemet som orsakade felet innan programmet kan försöka utföra åtgärden igen.
Öppna: ett begärande från programmet misslyckas omedelbart och ett undantag returneras till programmet.
Halvöppet: ett begränsat antal begäranden från programmet tillåts passera och anropa åtgärden. Om de här begärandena lyckas förutsätts det att det tidigare felet har åtgärdats och kretsbrytaren växlar till Stängt tillstånd (felberäkningen återställs). Om någon begäran misslyckas förutsätter kretsbrytaren att felet fortfarande finns så att det återgår till Öppna tillstånd och startar om timeout-timern för att ge systemet ytterligare en tidsperiod att återställa från felet.
Halvöppet tillstånd är användbart för att förhindra att en tjänst som håller på att återställas plötsligt översvämmas med begäranden. När en tjänst håller på att återställas kanske den har stöd för ett begränsat antal begäranden tills återställningen är slutförd, men medan återställningen pågår kan ett arbetsflöde göra så att tjänsten pausas eller misslyckas igen.
På bilden visas räknaren för misslyckande som används av Stängt tillstånd och är tidsbaserad. Den återställs automatiskt med jämna mellanrum. Den här designen hjälper till att förhindra att kretsbrytaren kommer in i tillståndet Öppna om den drabbas av tillfälliga fel. Tröskelvärde för fel som ställer kretsbrytaren i Öppet tillstånd nås endast när ett angivet antal fel har inträffat under en angiven tidsperiod. Räknaren som används av Halvöppet tillstånd registrerar antalet lyckade försök att anropa åtgärden. Kretsbrytaren återgår till Stängt tillstånd efter att ett angivet antal på varandra följande åtgärdsanrop har lyckats. Om alla anrop misslyckas försätts kretsbrytaren omedelbart i Öppet tillstånd och räknaren för lyckade anrop återställs nästa gång den försätts i Halvöppet tillstånd.
Återställning av systemet hanteras externt, möjligtvis genom att återställa eller starta om en misslyckad komponent eller reparera en nätverksanslutning.
Mönstret Kretsbrytare ger stabilitet medan systemet återställer från ett fel och minimerar påverkan på prestandan. Det kan bidra till att bibehålla systemets svarstid genom att snabbt avvisa ett begärande om en åtgärd som troligen kommer att misslyckas, i stället för att vänta tills tidsgränsen för åtgärden nås eller aldrig returneras. Om kretsbrytaren utlöser en händelse när status ändras kan den här informationen användas för att övervaka hälsotillståndet för en del av systemet som skyddas av kretsbrytaren eller varna en administratör när en kretsbrytare sätts i Öppet tillstånd.
Mönstret är anpassningsbart och kan anpassas enligt typen av det möjliga felet. Du kan till exempel använda en ökande timeout-timer för en kretsbrytare. Du kan placera kretsbrytaren i Öppna tillstånd i några sekunder från början, och sedan öka tidsgränsen till några minuter om felet inte har lösts och så vidare. I vissa fall kan det vara användbart att återgå till ett standardvärde som är av betydelse för programmet istället för att Öppet tillstånd returnerar fel och utlöser ett undantag.
Kommentar
Traditionellt förlitade sig kretsbrytare på förkonfigurerade tröskelvärden, till exempel antal fel och tidsgränsvaraktighet, vilket resulterade i ett deterministiskt men ibland suboptimalt beteende. Anpassningsbara tekniker som använder AI och ML kan dock dynamiskt justera tröskelvärden baserat på realtidstrafikmönster, avvikelser och historiska felfrekvenser, vilket gör kretsbrytaren mer motståndskraftig och effektiv.
Problem och överväganden
När du bestämmer hur det här mönstret ska implementeras bör du överväga följande punkter:
Undantagshantering: Ett program som anropar en åtgärd via en kretsbrytare måste vara redo att hantera undantagen som uppstår om åtgärden inte är tillgänglig. Hanteringen av undantag är specifikt för programmet. Till exempel kan ett program tillfälligt försämra dess funktioner, anropa en annan åtgärd i ett försök att genomföra samma uppgift eller hämta samma data, eller rapportera undantag för användaren och be dem att försök igen senare.
Typer av undantag: En begäran kan misslyckas av många orsaker, varav vissa kan tyda på en allvarligare typ av fel än andra. En begäran kan till exempel misslyckas eftersom en fjärrtjänst har kraschat och tar flera minuter att återställa, eller på grund av en timeout på grund av att tjänsten är tillfälligt överbelastad. En kretsbrytare kan eventuellt undersöka undantagstyperna som inträffar och justera dess strategi beroende på undantagens egenskaper. Det kan till exempel kräva ett större antal timeout-undantag för att köra kretsbrytaren till tillståndet Öppna jämfört med antalet fel på grund av att tjänsten är helt otillgänglig.
Övervakning: En kretsbrytare bör ge tydlig observerbarhet i både misslyckade och lyckade begäranden, vilket gör det möjligt för driftteam att utvärdera systemets hälsa. Använd distribuerad spårning för synlighet från slutpunkt till slutpunkt mellan tjänster.
Återställningsbarhet: Du bör konfigurera kretsbrytaren så att den matchar det troliga återställningsmönstret för den åtgärd som den skyddar. Om kretsbrytaren exempelvis förblir i Öppet tillstånd under en lång period kan undantag utlösas även om anledningen till felet har åtgärdats. På samma sätt kan en kretsbrytare fluktuera och minska programmets svarstid om den växlar från Öppet tillstånd till Halvöppet tillstånd för snabbt.
Testningen misslyckades: I tillståndet Öppna, i stället för att använda en timer för att avgöra när du ska växla till tillståndet Halvöppen, kan en kretsbrytare i stället regelbundet pinga fjärrtjänsten eller resursen för att avgöra om den blir tillgänglig igen. Den här pingen kan fungera som ett försök att anropa en åtgärd som tidigare misslyckats eller så kan den användas som en särskild åtgärd som tillhandahålls av fjärrtjänsten för testning av tjänstens hälsotillstånd, så som beskrivs av Health Endpoint Monitoring pattern (Övervakningsmönster för slutpunktens tillstånd).
Manuell åsidosättning: I ett system där återställningstiden för en misslyckad åtgärd är mycket varierande är det fördelaktigt att tillhandahålla ett manuellt återställningsalternativ som gör att en administratör kan stänga en kretsbrytare (och återställa felräknaren). På samma sätt kan en administratör tvinga en kretsbrytare till Öppna tillstånd (och starta om timeout-timern) om åtgärden som skyddas av kretsbrytaren är tillfälligt otillgänglig.
Concurrency: Samma kretsbrytare kan nås av ett stort antal samtidiga instanser av ett program. Implementeringen bör inte blockera samtida begäranden eller tillföra ytterligare overhead för varje anrop till en åtgärd.
Resursdi differentiering: Var försiktig när du använder en enda kretsbrytare för en typ av resurs om det kan finnas flera underliggande oberoende leverantörer. I exempelvis ett datalager som innehåller flera shards kan en shard vara fullt åtkomlig medan andra upplever ett tillfälligt fel. Om felsvaren i de här scenariona slås samman kan ett program försöka komma åt vissa shards, även när ett fel är högst troligt, medan åtkomst till andra shards kan vara blockerade trots att det är troligt att det skulle lyckas.
Accelererad krets som bryter: Ibland kan ett felsvar innehålla tillräckligt med information för att kretsbrytaren ska kunna snubbla omedelbart och hålla sig snubblad under en minsta tid. Felsvar från en delad resurs som är överbelastad kan till exempel indikera att det inte rekommenderas att omedelbart försöka igen och att programmet stället ska försök igen om några minuter.
distributioner i flera regioner: En kretsbrytare kan utformas för distributioner i en eller flera regioner. Det senare kan implementeras med hjälp av globala lastbalanserare eller anpassade regionmedvetna kretsbrytningsstrategier som säkerställer kontrollerad redundans, svarstidsoptimering och regelefterlevnad.
Service Mesh-kretsbrytare: Kretsbrytare kan implementeras på programskiktet eller som en övergripande, abstrakt funktion. Tjänstnät stöder till exempel ofta kretsbrytning som en sidovagn eller som en fristående funktion utan att ändra programkoden.
Kommentar
En tjänst kan returnera HTTP 429 (för många begäranden) om den begränsar klienten eller HTTP 503 (tjänsten är inte tillgänglig) om tjänsten inte är tillgänglig för närvarande. Svaret kan innehålla ytterligare information, till exempel fördröjningens förväntade varaktighet.
Att spela upp misslyckade begäranden: I tillståndet Öppna, i stället för att bara misslyckas snabbt, kan en kretsbrytare också registrera information om varje begäran till en journal och ordna så att dessa begäranden spelas upp igen när fjärrresursen eller tjänsten blir tillgänglig.
Olämpliga tidsgränser för externa tjänster: En kretsbrytare kanske inte helt kan skydda program från åtgärder som misslyckas i externa tjänster som har konfigurerats med en lång tidsgräns. Om tidsgränsen är för lång kan en tråd som kör en kretsbrytare blockeras under en längre period innan kretsbrytaren anger att åtgärden har misslyckats. Under den här tiden kan många andra programinstanser också försöka anropa tjänsten via kretsbrytaren och foga samman ett betydande antal trådar innan de misslyckas.
Anpassningsbarhet till beräkningsdiversifiering: Kretsbrytare bör ta hänsyn till olika beräkningsmiljöer, från serverlösa till containerbaserade arbetsbelastningar, där faktorer som kallstart och skalbarhetspåverkande felhantering. Anpassningsbara metoder kan dynamiskt justera strategier baserat på beräkningstypen, vilket säkerställer motståndskraft mellan heterogena arkitekturer.
När du ska använda det här mönstret
Använd det här mönstret:
- För att förhindra sammanhängande fel genom att stoppa överdrivna anrop av en fjärrtjänst eller åtkomstbegäranden till en delad resurs om dessa åtgärder är mycket benägna att misslyckas.
- För att förbättra motståndskraften i flera regioner genom att dirigera trafik intelligent baserat på felsignaler i realtid.
- För att skydda mot långsamma beroenden hjälper du dig att hålla jämna steg med dina servicenivåmål (SLO) och för att undvika prestandaförsämring på grund av tjänster med långa svarstider.
- Hantera tillfälliga anslutningsproblem och minska begärandefel i distribuerade miljöer.
Det här mönstret rekommenderas inte:
- För hantering av åtkomst till lokala privata resurser i ett program, till exempel InMemory-datastruktur. I den här miljön skulle en kretsbrytare lägga till overhead i systemet.
- Som ett substitut för att hantera undantag i ditt programs affärslogik.
- När välkända återförsöksalgoritmer räcker och dina beroenden är utformade för att hantera återförsöksmekanismer. Om du implementerar en kretsbrytare i ditt program i det här fallet kan du lägga till onödig komplexitet i systemet.
- När du väntar på att en kretsbrytare ska återställas kan det medföra oacceptabla fördröjningar.
- Om du har en meddelandedriven eller händelsedriven arkitektur, eftersom de ofta dirigerar misslyckade meddelanden till en kö med obeställbara meddelanden (DLQ) för manuell eller uppskjuten bearbetning. De inbyggda felisolerings- och återförsöksmekanismerna som vanligtvis implementeras i de här designerna räcker ofta.
- Om återställning av fel hanteras på infrastruktur- eller plattformsnivå, till exempel med hälsokontroller i globala lastbalanserare eller tjänstnät, kanske kretsbrytare inte behövs.
Design av arbetsbelastning
En arkitekt bör utvärdera hur kretsbrytarmönstret kan användas i arbetsbelastningens design för att uppfylla de mål och principer som beskrivs i grundpelarna i Azure Well-Architected Framework. Till exempel:
Grundpelare | Så här stöder det här mönstret pelarmål |
---|---|
Beslut om tillförlitlighetsdesign hjälper din arbetsbelastning att bli motståndskraftig mot fel och se till att den återställs till ett fullt fungerande tillstånd när ett fel inträffar. | Det här mönstret förhindrar överlagring av ett felberoende. Du kan också använda det här mönstret för att utlösa en graciös försämring i arbetsbelastningen. Kretsbrytare är ofta kopplade till automatisk återställning för att ge både självbevarelsedrift och självåterställning. - RE:03 Analys av felläge - RE:07 Tillfälliga fel - RE:07 Självbevarande |
Prestandaeffektivitet hjälper din arbetsbelastning att effektivt uppfylla kraven genom optimeringar inom skalning, data och kod. | Det här mönstret undviker metoden för återförsök på fel, vilket kan leda till överdriven resursanvändning under beroendeåterställning och kan även överbelasta prestanda för ett beroende som försöker återställa. - PE:07 Kod och infrastruktur - PE:11 Live-problem svar |
Som med alla designbeslut bör du överväga eventuella kompromisser mot målen för de andra pelarna som kan införas med det här mönstret.
Relaterade resurser
Följande mönster kan vara användbara när du implementerar det här mönstret:
Tillförlitligt webbappmönster visar hur du tillämpar kretsbrytarmönstret på webbprogram som konvergerar i molnet.
Återförsöksmönster. Beskriver hur ett program kan hantera tillfälliga fel som är väntade när det försöker ansluta till en tjänst eller nätverksresurs genom att transparent försöka utföra en åtgärd som tidigare misslyckats igen.
Hälsoslutpunktsövervakningsmönster. En kretsbrytare kan eventuellt testa en tjänsts hälsa genom att skicka ett begärande till en slutpunkt som exponeras av tjänsten. Tjänsten ska returnera information med dess status.