Wyłącznik i degradacja
Wyłącznik (CB) to wzór zabezpieczeń, który przerywa połączenia do zdegradowanej zależności, aby zlokalizować awarię i chronić usługi upstream i użytkownika. Degradacja (wdzięczna degradacja) - celowe uproszczenie funkcjonalności w przypadku braku zasobów lub awarii (na przykład zwracanie danych buforowanych/niekompletnych, wyłączanie „drogich” funkcji) bez pełnego przestoju.
Głównym celem jest zachowanie SLO i doświadczenia użytkownika poprzez kontrolowane awarie, zamiast kaskadowych kropli.
1) Kiedy stosować
Zależność jest niestabilna: wzrost p95/p99, terminy, błędne odpowiedzi.
Zewnętrzne interfejsy API z rygorystycznymi limitami/karami.
„Ciężkie” oparcia (wyszukiwanie, zalecenia, raporty), gdzie przekłady nasilają burzę.
Obszary wysoce obciążone z ryzykiem wyczerpania basenów (połączenia, nici).
2) Stany BC i przejścia
Klasyczny potrójny:1. Zamknięte - ruch drogowy, liczone są wskaźniki błędów/opóźnień.
2. Otwarte - połączenia są natychmiast odrzucane (fail-fast) i/lub przenoszone na fallback.
3. Half-Open - Ograniczona liczba zapytań „próbnych” określa, czy zamknąć przełącznik.
Wyzwalacze otwierające
Próg błędu/wyczerpania czasu na okno (na przykład ≥ 50% ostatniego N).
Próg opóźnienia (np. p95> cel).
Połączone zasady (przekroczone błędy - timeout).
Czas wstrzymania (chłodzenie)
Stałe (na przykład 10-60 sekund) lub adaptacyjne (wzrost wykładniczy z powtarzającymi się uruchomieniami).
3) Timeouts, rekolekcje i jitter
Terminy są zawsze krótsze niż przed SLO i są propagacją terminów.
Retrai tylko dla operacji idempotentnych; 1-2 próby są wystarczające w większości przypadków.
Backoff + jitter (full jitter) zapobiega synchronicznym falom powtórzeń.
Zabezpieczenie (żądania zapasowe) - ekonomiczne i tylko dla bardzo krytycznych odczytów.
4) Izolacja grodziowa i „bezpieczniki”
Oddzielne pule połączenia/pracownika/kolejki według domeny i typu ruchu (VIP, zadania w tle, publiczne interfejsy API).
Czapki dotyczące współistnienia operacji „drogich”.
Kontrola wstępu: łatwa awaria przed wykonaniem, gdy kolejka jest pełna.
5) Scenariusze awarii i degradacji
Opcje
Odpowiedzi w cache/stylu: 'stale-while-revalidate', zwracając dane z L2/L3 pamięci podręcznej.
Tylko do odczytu: blok zapisu/poleceń, pozwalają na bezpieczne odczyty.
Reakcje zastępcze: niepełne dane (np. brak zaleceń/awatarów).
Wyłączanie funkcjonalne: tymczasowo ukryć niekrytyczne widżety/funkcje.
Flagi funkcji: szybka zmiana zachowania bez zwolnienia.
Zasady
Awaria musi być deterministyczna, szybka i bezpieczna od danych.
Wyraźnie zaznaczyć zdegradowaną ścieżkę w logach/utworach/metrykach.
6) Ustalanie priorytetów i kształtowanie ruchu
Plany VIP/płatne - wyższy priorytet/kwoty w przypadku niedoboru.
Limity stawek i zmniejszanie obciążeń związanych ze zdegradowanymi zależnościami.
Obciążenie szopy: miękka redukcja jakości (np. mniej wyników, obcięte obrazy) aż do ustabilizowania.
7) Obserwowalność i sygnalizacja
Metryka CB
Status (zamknięty/otwarty/półotwarty) i czas trwania stanu.
Udział awarii według przyczyn: CB-open, timeout, 5xx, retry-wyczerpany.
p95/p99 opóźnienie „przed” i „po” przełącznik.
Liczba/odsetek wniosków za pomocą awarii.
Odwzorowanie
Adnotacje przęseł: 'circuit = open', 'fallback = cache', 'admission = refused'.
Korelacja z limitami (429/ Limit-), kolejkami i kulami połączeń.
Dzienniki/audyty
Powód otwarcia/zamknięcia, progi, identyfikatory zależności.
8) Umowy i protokół
HTTP
Failil-fast: '503 Service Unavailable' z 'Retry-After' (lub '429' z limitami).
Zawartość częściowa/stała: „200 ”/„ 206” z metadanymi degradacji (na przykład „X-degraded: true”).
Polityka pamięci podręcznej: „Cache-Control: stale-if-error, stale-while-revalidate”.
gRPC
„NIEDOSTĘPNY”, „DEADLINE _ EXCEEDED”, przekłada semantykę według zasad klienta/proxy.
Termin/termin dotyczący kontekstu wniosku; rozłożenie terminu w dół łańcucha.
Idempotencja
"Idempotency-Key 'dla operacji POST, deduplication na granicy.
9) Typowe wdrożenie (kod pseudo)
pseudo onRequest(req):
if circuit. isOpen(dep):
return fallbackOrFail(req)
with timeout(T):
try:
resp = call(dep, req)
circuit. recordSuccess(dep, latency=resp. latency)
return resp except TimeoutError or 5xx as e:
circuit. recordFailure(dep)
if circuit. shouldOpen(dep):
circuit. open(dep, coolDown=adaptive())
return fallbackOrFail(req)
Próbka w połowie otwarta
pseudo onTimer():
if circuit. state(dep) == OPEN and coolDownExpired():
circuit. toHalfOpen(dep)
onRequestHalfOpen(req):
if circuit. allowTrial (dep): # e.g. 1 try: call -> success => close catch: reopen with longer coolDown else:
return fallbackOrFail(req)
10) Ustalanie progów
Okno obserwacyjne: przesuwne N sekundy/zapytania.
Próg błędu: 20-50% w oknie (w zależności od profilu).
Próg opóźnienia: p95 ≤ docelowe SLO (np. 300-500 ms); nadwyżka jest liczona jako „błąd” dla BC.
Adaptacyjne chłodzenie: 10s → 30s → 60s z wielokrotnymi uruchomieniami.
11) Praktyki testowania i chaosu
Chaos: wtrysk błędu opóźnienia/zależności, awaria DNS, spadek pakietu.
Dni gry: rozpoczęcie „otwarcia” przełącznika na środowisku bojowym, sprawdzanie awaryjnego.
Canary: Najpierw włącz politykę POC/degradacji dla 1-5% ruchu.
Budżet SLO: zezwalać na eksperymenty do czasu wyczerpania budżetu na błędy.
12) Integracja z wielopoziomowym
Stan BC może być przechowywany na zależność od lokatora (dla najemców hałaśliwych) lub globalnie - w zależności od profilu obciążenia.
Segment danych i buforów awaryjnych przez 'lokator _ id'.
Priorytety/kwoty - zgodnie z planami (VIP nie powinny cierpieć z powodu zachowania Starter).
13) Lista kontrolna przedsprzedaży
- Terminy i terminy są ostateczne i spójne.
- Przekłady są ograniczone, tylko dla operacji idempotent, z backoff + jitter.
- Progi BC są uzasadnione danymi z badań obciążenia.
- Ścieżki awaryjne istnieją, szybkie i bezpieczne; cache polityki zdefiniowane.
- Izolacja grodziowa: oddzielne puli/kolejki/limity.
- Wskaźniki/ścieżki/kłody degradacji bandery i stany BC.
- Dokumentacja umowy odpowiedzi (HTTP/gRPC) z przykładowymi nagłówkami/kodami.
- Scenariusze chaosu i dni gry odbywają się regularnie; Jest książka startowa.
14) Typowe błędy
Nie ma żadnych terminów → rekolekcje „całą drogę” i upadki kaskadowe.
Pojedynczy globalny BC zamiast selektywny (według punktu końcowego/metody) - niepotrzebne awarie.
Otwórz przełącznik bez awaryjnego → „puste” ekrany zamiast zdegradowanego UX.
Retrai bez jitter → synchroniczne burze wniosków.
Długie chłodzenie z krótkotrwałymi awariami lub zbyt krótkie ze stabilnymi - stwierdzeniami „flip-flop”.
Brak grodzi - wyczerpanie wspólnych basenów i „blokowanie głowicy linii”.
15) Szybki wybór strategii
Odczyty o dużym znaczeniu: CB + pamięć podręczna ciągłych odpowiedzi + zabezpieczenie (ekonomiczne).
Rekordy/płatności: stricte timeouts, minimum retrays, idempotence keys, no brudny fallback.
Zewnętrzne API: CB z agresywnymi progami, adaptacyjne chłodzenie, ścisłe rozdrabnianie.
Mikroserwice obciążeniowe pulsujące: grodzie, czapki na kojarzenie, priorytety VIP.
Wnioski
Wyłącznik i zarządzana degradacja to architektura „ubezpieczenia”: przekładają chaotyczne awarie na przewidywalne zachowanie. Przezroczyste czasy, ograniczone rekolekcje jitter, izolowane baseny, przemyślane ścieżki awaryjne i telemetria sprawiają, że system jest odporny na awarie zależności i utrzymuje SLO nawet w okresach szczytu i katastrofy.