De tre felkoncepten som är värda att känna till
Välkommen
Distribuerade system felar i mönster. När du lär dig mönstren blir varje postmortem ett igenkännande övning istället för ett mysterium.
Tre koncept täcker det mesta av det som är viktigt vid analys av produktionsfel:
Enkelsviktspunkt (SPOF): en komponent vars fel kan ta ner ett större system. Ofta dolt: DNS-servern som alla är beroende av; certifikatet som allt förnyas mot; den enskilda databasmastern.
Kaskadskada: ett komponentfel orsakar ett annat, som i sin tur orsakar ett tredje. En långsam databas orsakar tidsåtgångar i API-lagret, vilket leder till nya försök, vilket belastar databasen ytterligare, vilket i sin tur orsakar fler tidsåtgångar. Skadan sprider sig.
Skadeomfattning: hur mycket av systemet som går ner när en del felar. Arkitekturella val antingen begränsar eller obegränsar omfattningen. En SPOF (single point of failure) har obegränsad skadeomfattning. En tjänst med bulkhead-arkitektur har begränsad omfattning.
Till slutet av denna lektion kommer du att:
- Identifiera SPOF:er i en arkitektur genom inspektion
- Erkänna mönster för kaskadskador: åskhjord (thundering herd), återförsöksstorm (retry storm), dödskö (queue of death)
- Läsa en verklig tidslinje och skilja utlösaren från den latenta defekten som utlösaren framkallade
- Skriv skuldfrifriande åtgärder som riktar sig mot system istället för människor, och som täcker förebyggande / upptäckt / återhämtning
- Resonera om bulkheads och circuit breakers som verktyg för att begränsa skadeomfattningen
Hitta den enskilda felkällan
Inspektion av lagerbaserad arkitektur
Tänk på en liten webbarkitektur:
- DNS: api.example.com -> en enskild namnserver-IP 203.0.113.10 som hostas av en DNS-leverantör
- CDN: en enskild CDN-leverantör framför api.example.com
- Ingress: två omvända proxy-maskiner bakom en lastbalanserare
- Backend: sex API-replikater i två tillgänglighetszoner (tre per zon)
- Databas: en primär + en läsreplikat, i samma tillgänglighetszon
- Cache: Redis-cluster, tre noder utspridda över samma två tillgänglighetszoner
Fråga: vilka komponenter är SPOF:er? Tips: SPOF:er är inte alltid den uppenbara typen 'en enskild maskin'. En kluster med tre maskiner i samma tillgänglighetszon är en SPOF för den zonens fall.
Tre klassiska kaskadmönster
Misslyckanden sprids genom beroenden
Mönster 1: Åskande hjord. En delad resurs (cache, lås, databas) misslyckas eller startas om. Alla klienter som var beroende av den gör om anropet samtidigt. Översvämningen överväldigar det som kommer upp igen; omförsöken staplas upp snabbare än återställningen kan absorbera dem; återställningen slutförs aldrig.
Mönster 2: Omförsöksstorm. En nedströmslig tjänst blir långsam. Upströmsliga anropare gör om anropet istället för att misslyckas. Omförsökerna multiplicerar den ursprungliga belastningen. Den långsamma tjänsten blir ännu långsammare, vilket utlöser fler omförsök. Till slut överstiger belastningen även en frisk version av tjänsten.
Mönster 3: Dödskön. En bearbetningskö utan backpressure tar emot snabbare än den bearbetar. Köen växer obegränsat. Minnet töms; konsumenten kraschar; startas om; hittar en ännu större kö; kraschar igen.
Gemensam tråd: en liten initial störning utlöser en positiv återkopplingsslinga. Systemets egen respons förstärker misslyckandet istället för att dämpa det.
Dämpningsmekanismer
Exponentiell backoff med jitter. Klienter som gör om väntar längre varje gång, med en slumpmässig förskjutning. Förhindrar synkroniserade omförsöksvågor.
Circuit breaker (Felsäkring). En anropare håller koll på felet hos nedströmsenheterna. När en tröskel överskrids, slutar anroparen att anropa under en avkylningstid och misslyckas omedelbart med sina egna anrop istället. Förhindrar slösat arbete och låter nedströmsenheten återhämta sig.
Bulkhead (Sjunklucka). Isolera resurser per beroende. Anslutningspool A för databasen, en separat anslutningspool B för cachen. En långsam databas kan inte svälta alla anslutningar; anrop till cachen fortsätter.
Load shedding (Lastavlastning). Vid överbelastning, släng bort förfrågningar vid kanten istället för att acceptera dem och misslyckas långsamt. Ett 429 på 1 ms är bättre än ett 500 på 30 sekunder.
Backpressure (Mottryck). Sakta ner producenter när konsumenter inte hinner med. Köer blir begränsade; sändare blockeras; den ursprungliga källan till arbetet känner av friktionen.
Diagnostisera en kaskad
Ett teams API-nivå kollapsar under en rutinmässig databasfailover. Tidsplan:
- 14:00:00 — Operatören främjar standby-databasen. Förväntad tillgänglighetsnedsättning: ~10 sekunder.
- 14:00:08 — Primärnoden är otillgänglig. API-lagrets begäranden börjar misslyckas med databasanslutningsfel.
- 14:00:08 — API-lagret gör nya försök (standardkonfiguration: 5 försök, ingen backoff, 100 ms mellanrum).
- 14:00:11 — Standby-noden är främjad och accepterar nya anslutningar.
- 14:00:11 — API-lagret öppnar tusentals nya databasanslutningar samtidigt (varje replik × varje samtidiga begäran × varje nytt försök).
- 14:00:13 — Den nya primärnodens anslutningspool är uttömd; nya anslutningar avvisas.
- 14:00:13-14:05:00 — API-lagrets repliker tömmer sina anslutningspools, kastar undantag, kraschar, startas om och upprepas.
- 14:05:00 — Operatören stoppar manuellt trafiken till API-lagret; databasen stabiliseras.
- 14:10:00 — graduell återställning av trafiken slutförs. Totalt avbrott: ~10 minuter (jämfört med förväntade ~10 sekunder).
DNS SERVFAIL: Två sammanflätade fel
En postmortem med verklig struktur
Nedan följer en rensad version av ett verkligt incident. Leverantörsnamn har ändrats och IP-adresser har anonymiserats; strukturen, tidsaxeln och lärdomarna är dock verkliga.
Sammanfattning
Webbplatsen example.com returnerade SERVFAIL från alla publika DNS-resolventer i ungefär 3–4 timmar. Alla övriga 46 zoner på samma DNS-master påverkades inte. Rotorsak: två sammanflätade fel.
1. Leverantör A (en sekundär DNS-leverantör) lade till en ny intern synkroniserings-IP som inte fanns i primärns allow-axfr-ips-vitlista.
2. Zonen example.com hade ett åratal gammalt RFC-stridande CNAME-konflikt (demo.example.com hade både CNAME- och MX/TXT-poster på samma etikett) som fick Leverantör A att avvisa zonen vid ny AXFR.
Tidsaxel (UTC)
- ~15:00 — Leverantör A lägger till den nya synkroniserings-IP:en 198.51.100.42 i sin infrastruktur
- 15:02 — första AXFR-out denied för 198.51.100.42 syns i primära DNS-loggar (inga larm för denna signal)
- ~18:00 — SOA-expirationsfönstret nås; Leverantör A tar bort example.com-zonen från cachen
- ~18:30 — SERVFAIL upptäcks externt
- ~19:45 — grundorsak identifierad
- 20:00 — 198.51.100.42 läggs till i allow-axfr-ips; primärn startas om
- 20:05 — NOTIFY skickas; AXFR initieras; zonen ger fortfarande SERVFAIL (CNAME-konflikt)
- 20:07 — check-zone avslöjar 1 fel: CNAME-konflikt på demo.example.com
- 20:09 — CNAME ersattes med A-post; zonskontroll ren (0 fel)
- 20:10 — NOTIFY skickades; AXFR slutfördes; Leverantör A börjar servera zonen
- 20:11 — dig @8.8.8.8 example.com A returnerar korrekt IP — ÅTGÄRDAT
Varför bara example.com?
Alla 47 zoner delar samma DNS-huvudserver. AXFR-IP-blockeringen påverkade alla zoner. Men bara example.com hade CNAME-konflikten, & bara example.com behövde en ny AXFR vid det tillfälle då neket tillämpades. Andra zoner hade redan uppdaterats innan neket eller behövde inte det ännu.
Latent fel
CNAME-konflikten vid demo.example.com hade funnits i åratal. Det fungerade eftersom huvudservern serverade zonen från sin databas (tolerant mot RFC-överträdelser) & Leverantör A serverade från utdaterad cachad data från innan överträdelsen introducerades. När Leverantör A tömde sin cache & behövde ny data, framträdde överträdelsen.
Utlösare
Leverantör A lade tyst till en ny synkroniserings-IP. Primärns tillåtandelista innehöll inte den. AXFR nekas. Tre timmar senare (SOA expire) släppte Leverantör A zonen. Den latenta defekten framträdde när systemet försökte återställa sig.
Skriv skuldfrifriande åtgärder
Skuldfrifriande: Rikta mot system, inte människor
En skuldfrifriande åtgärd anger något som systemet bör göra annorlunda, inte något som en person bör göra annorlunda. 'Träna operatören' är skuldbeläggande. 'Lägg till en automatisk kontroll som fångar detta innan utgivning' är skuldfrifriande.
Bra skuldfrifriande åtgärder grupperas i tre dimensioner:
- Förebyggande: gör det svårare eller omöjligt att det onda inträffar
- Detektion: upptäck det tidigare om det inträffar
- Återhämtning: begränsa skadan när det inträffar
Varje post ska ange (1) den specifika systemförändringen, (2) ett ansvarigt team och (3) vilken dimension den tillgodoser.
Kompartiment som sjunker utan skeppet
Lånat från skeppsbyggnadskonst
Skepp har vattentäta skott: vertikala väggar som delar upp skrovet i kompartiment. Ett kompartiment kan översvämmas utan att skeppet sjunker; ett annat kan gå sönder utan att påverka resten.
Distribuerade system lånar samma ord och samma idé.
Bulkhead-mönster: isolera resurser per beroende. En tjänst som anropar tre nedströms-API:er använder tre separata anslutningspooler, tre separata trådpooler och tre separata återförsöksbudgetar. Ett långsamt eller felaktigt nedströmsberoende kan inte konsumera de resurser som är tilldelade de andra två.
Utan bulkheads: ett långsamt beroende tömmer den gemensamma trådpoolen; anrop till andra beroenden blockeras och väntar på trådar; hela tjänsten blir oresponsiv.
Med bulkheads: ett långsamt beroende tömmer sin egen pool; anrop till det misslyckas snabbt; anrop till andra beroenden fortsätter normalt; spridningsradien hålls begränsad till det felaktiga beroendet.
Säkringsbrytare
Circuit breaker-mönster: ett tillståndsbaserat skal runt en nedströmsberoende som spårar felrate. Tre tillstånd:
- Stängd (normal): anrop släpps igenom. Fel räknas.
- Öppen (utlöst): när en feltröskel överskrids (t.ex. 50 % fel under de senaste 30 sekunder), öppnas brytaren. Anrop misslyckas omedelbart utan att försöka nå beroendet. Sparar anroparen från slösaktigt arbete; skyddar beroendet från att ta emot last medan det är ohälsosamt.
- Halvöppen (test): efter en avkylningsperiod släpper brytaren igenom en liten del av anropen. Om de lyckas, stängs den tillbaka till normal. Om de misslyckas, öppnas den igen för en ny avkylningsperiod.
Den centrala insikten: circuit breakern förhindrar slöseri med resurser under kända ohälsosamma perioder & ger nedströmskomponenten en chans att återhämta sig utan fortsatt last.
Bulkheads begränsar spridningsradien. Circuit breakers förhindrar att spridningen upprätthålls.
Begränsa spridningsradien
Din API-tjänst anropar fyra nedströmstjänster: User Service, Recommendation Service, Notification Service & en tredjeparts Payment API. Teamet har hört att 'Recommendation Service har varit lite flakig' & vill säkerställa att när den misslyckas, förblir resten av systemet hälsosamt.
Idag använder tjänsten en enda delad trådpool med 200 trådar och en enda delad HTTP-anslutningspool. Alla fyra nedströmsberoenden konkurrerar om dessa resurser. Det finns inga säkringsbrytare.
Designa en felsläktsgranskning
Sammanfattning
Du har lärt dig att upptäcka SPOF:er genom inspektion, känna igen mönster för kaskadfel, skilja utlösare från latent felaktighet när du läser en postmortem, skriva skuldfrifriande åtgärder över prevention / detektion / återhämtning, & begränsa spridningsradie med bulkheads + circuit breakers + graciös degradering.
Applicera alla fem.
Ditt team lanserar en ny tjänst search.example.com som beror på tre nedströms-tjänster: en primär sökindeks (index.example.com), en analytiktjänst (analytics.example.com), & en rekommendationstjänst (recs.example.com). Teamet vill att du ska leda en 'felsläktsgranskning' innan lanseringen.
Vart denna kurs går vidare
Vart denna kurs går vidare
Du kan nu identifiera en SPOF, känna igen en kaskad, läsa en postmortem produktivt, skriva skuldfrifriande åtgärdsplaner och begränsa spridningsradie genom design.
Den sista lektionen i denna kurs (cs_distsys_observability_and_capacity) lär dig vad du ska mäta så att du upptäcker ett problem innan användarna gör det. Hälsokontroller, versionsändpunkter, de fyra guldstandarderna på en proxy-nivå och hur beslut om ökad kapacitet kopplas till observerad data.
Sällskapslektion: geometry_of_failure_modes_and_blast_radius härleder mellanhetssentralitet (vilken grafknut är flaskhalsen) och min-cut (gränsen för spridningsradie).
Bra jobbat. Framåt.