Logo GH

Circuit Breaker және ретрайлер

Circuit Breaker және ретрайлер

1) Бұл не үшін қажет

Желiлер сенiмсiз: жасырындылық пульсацияланады, тораптар құлдырады, лимиттерге қол жеткiзiледi. Ретраялар қысқа мерзімді іркілістерден құтқарады, ал Circuit Breaker жүйені каскадтық істен шығудан және «өзін-DDoS» қорғайды. Дұрыс таймауттар мен лимиттердің комбинациясы SLO-ны сақтайды, артқы кідірістерді және «тоғыздардың» бағасын тұрақтандырады.

2) Базалық қағидаттар

Алдымен таймауттар, содан кейін ретрациялар, содан кейін Circuit Breaker.
Ретраим тек идемпотенттік операциялар (GET, қауіпсіз POST/PUT идемпотенттік кілтпен).
Ретрациялардың бюджетін бөліңіз: маршрутқа бастапқы RPS-тен 10-15% ≤.
Істен шығуды оқшаулаңыз: bulkhead (бөлек пулдар/квоталар) + rate-limit.
Тозу кезінде - жылдам істен шығу (fail-fast), graceful-degradation/бітеуіштер.

3) Ретрайлардың семантикасы

Қашан тегістеу

Транзиент қателері: timeouts, 5xx, желілік қолжетімсіздік, 429 ('Retry-After' кейін).
Ретрациялауға болмайды: айқын бизнес-қателер (4xx ≠ 429), теңсіздіксіз side-effects (кілтсіз төлем).

Стратегиялар

Exponential backoff + jitter (толық немесе біркелкі): ретрайлер тобын тегістейді.
Max attempts: 1-2 (сирек 3) - әдетте көбірек зиянды.
Budget: сервистік және per-request «retry tokens» жаһандық ретрай/сек есептеуіші.
Hedging (сирек): t-квантилден (p95) кейін сұрау салудың қатарлас қосарлануы - тек қатаң демпотенттік оқу үшін.

backoff + джиттер псевдодосы:
python base = 100 # ms for attempt in range(1, max_attempts+1):
try:
return call()
except Transient as e:
if attempt == max_attempts: raise sleep_ms = min(cap_ms, base 2(attempt-1))
sleep(random(0, sleep_ms)) # full jitter

4) Таймауттар және «жылдам істен шығу»

Client timeout <upstream timeout: «зомби» сұрауларын жинақтамау үшін.
Делите: connect timeout, read timeout, overall deadline.
Tail-aware таймауттар: p95/p99 + шағын қорды көздейміз.
gRPC 'deadline' дегенді пайдаланып, оны тізбек бойынша төмен лақтырыңыз.

5) Circuit Breaker: қалай жұмыс істейді

Күй- жайы:
  • Closed: трафикті өткізіп жібереді, қателерді/жасырындылықты санайды.
  • Open: бірден жылдам бас тартады (немесе қосымша жауап).
  • Half-Open: тексеру сұраулары; табысты болған жағдайда - жабылады.
Ашу шегі:
  • Қателер/таймауттар N сұраулар/секунд терезесі үшін X% үлесінен асады немесе шектен жоғары p99.
  • Релевантты жылжымалы статистика және ең аз көлем (мысалы, 50 сұраудан ≥).

6) Bulkhead, квоталар және «бөлісу және билік ету»

per-upstream және per-фич қосылыстарының бөлек пулдары.
In-flight сұрауларына квоталар; артық - тез бас тарту.
Жетіспеушілік кезінде - төмен басымдықты фич деградациясы (feature flags).

7) Периметрмен интеграция (Envoy/Istio/Nginx)

Envoy (retry + outlier + CB, идея):
yaml routes:
- match: { prefix: "/api" }
route:
cluster: upstream_api timeout: 2s retry_policy:
retry_on: "connect-failure,reset,retriable-4xx,5xx"
num_retries: 2 per_try_timeout: 600ms retry_back_off: { base_interval: 100ms, max_interval: 800ms }
hedge_policy:
hedge_on_per_try_timeout: true initial_requests: 1 additional_request_chance: { numerator: 5, denominator: HUNDRED } # 5%
clusters:
- name: upstream_api circuit_breakers:
thresholds:
- priority: DEFAULT max_connections: 500 max_requests: 1000 max_retries: 200 outlier_detection:
consecutive_5xx: 5 interval: 5s base_ejection_time: 30s max_ejection_percent: 50
Istio (VirtualService fault/retry, қысылған мысал):
yaml apiVersion: networking. istio. io/v1beta1 kind: VirtualService spec:
hosts: ["payments"]
http:
- route: [{ destination: { host: payments } }]
timeout: 2s retries:
attempts: 2 perTryTimeout: 600ms retryOn: "5xx,connect-failure,refused-stream,reset"
Nginx Ingress (аңдатпалар):
yaml nginx. ingress. kubernetes. io/proxy-connect-timeout: "2"
nginx. ingress. kubernetes. io/proxy-read-timeout: "2"
nginx. ingress. kubernetes. io/proxy-next-upstream: "error timeout http_502 http_503 http_504"
nginx. ingress. kubernetes. io/proxy-next-upstream-tries: "2"

8) Кітапханалар және код (стек-сниппеттер)

Java (Resilience4j):
java var cb = CircuitBreaker. ofDefaults("psp");
var retry = Retry. of("psp-retry",
RetryConfig. custom()
.maxAttempts(2)
.waitDuration(Duration. ofMillis(200))
.intervalFunction(IntervalFunction. ofExponentialRandomBackoff(100, 2. 0, 0. 5) )//jitter
.retryExceptions(SocketTimeoutException. class, IOException. class)
.build());

Supplier<Response> decorated =
CircuitBreaker. decorateSupplier(cb,
Retry. decorateSupplier(retry, () -> client. call()));

return Try. ofSupplier(decorated)
.recover(BusinessException. class, fallback())
.get();
Go (context deadline + backoff):
go ctx, cancel:= context. WithTimeout(context. Background(), 2time. Second)
defer cancel()
var lastErr error for i:= 0; i < 2; i++ {
reqCtx, stop:= context. WithTimeout(ctx, 600time. Millisecond)
lastErr = call(reqCtx)
stop()
if lastErr == nil { break }
sleep:= time. Duration(rand. Intn(1<<uint(7+i))) time. Millisecond // full jitter time. Sleep(min(sleep, 800time. Millisecond))
}
if lastErr!= nil { return fastFail() }
Node. js (got + p-retry):
js import pRetry from 'p-retry';
await pRetry(() => got(url, { timeout: { connect: 500, request: 2000 } }), {
retries: 2,
factor: 2,
randomize: true,
minTimeout: 100,
maxTimeout: 800,
onFailedAttempt: e => { if (isBusiness(e)) throw e; }
});

9) Ретрайлардың және SLO бюджеті

retry tokens енгізіңіз: әрбір ретрай токенді жұмсайды; пул шектелген.
error-budget-пен байланыстырыңыз: burn-rate табалдырықтан жоғары болғанда - ретрацияны ажыратамыз, CB-ны жиі ашамыз, деградацияны қосамыз.
Канареялық релиздер: канареяларда әрекеттер мен токендерді азайтыңыз.

10) Hedging (абайлаңыз)

Жеңілгенді болдырмай, p95 мерзімінен кейін қосымша сұрауды іске қосыңыз.
Тек оқу және «қауіпсіз» демпотенттік операциялар үшін; үлесті шектеңіз (1-5% ≤).
Апстримге жүктеменің өсуін қадағалаңыз.

11) Бақылау

Rate, Error, Duration (p50/p95/p99) бағыттары бойынша RED-метриктер.
CB-метриктер: күйі (open/half-open), ашылу жиілігі, жіберіп алған/істен шыққан сұраулар.
Ретраилер: attempts/request, retry-rate, жағылған токендер.
Периметрі: outlier-ejection, ejection-rate.
Трестер: 'retry _ attempt', 'cb _ state', 'hedged = true' деп түсіндіріңіз, 'trace _ id' деп лақтырыңыз.

12) Сәулетпен интеграция

Bulkhead + CB әрбір сындарлы апстримге.
Кезектер/асинхрон: ақылсыз таймауттың орнына ұзақ операциялар үшін.
Кеш/бітеуіштер: fil-open кезінде сыни емес фич үшін.
Автоскейл: жаман ретрациялардың орнын толтырмайды - алдымен «дауылды» тоқтатыңыз.

13) Қарсы үлгілер

Таймаусыз ретрациялар → «салбыраған» коннектілер және пулдардың сарқылуы.
Демпотенттік емес операцияларды қайталау (екі рет есептен шығару).
Cap пен джиттерсіз шексіз экспоненциалды өсу.
Барлық апстримдерге бірыңғай CB → бүкіл өнімге бас тартуды сүйреу.
429/' Retry-After 'дегенді елемеу.
Клиенттің таймауты апстримге қарағанда ұзақ (немесе мүлдем емес).
Бизнес-қателерді ретралармен «емдеу».

14) Енгізу чек-парағы (0-30 күн)

0-7 күн

Бағыттарды және олардың ұқсастығын анықтаңыз.
Таймауттарды (connect/read/overall) орнатыңыз, әдепкі ең аз ретрайлерді (× 1) және CB қосыңыз.
Негізгі апстримдер үшін пулдарды/квоталарды (bulkhead) бөліңіз.

8-20 күн

Джиттер мен retry-rate бойынша жаһандық ретрайлардың бюджетін қосыңыз.
outlier-ejection параметрін периметрге орнатыңыз, low-prio үшін жылдам бас тарту.
RED + CB/Retry дашбордтары, белгілері бар трестер.

21-30 күн

Ретрайлардың канареялық профильдері (аз әрекеттер), game-day «апстрим баяу/флапер».
Саясатты құжаттаңыз: кім/не ретраит, шектер, ерекшеліктер.
p95/p99 және таймауттарды көзбен емес, деректермен қайта қараңыз.

15) Жетілу метрикасы

Маршруттардың 100% таймауттар және құжатталған ретрайлер/СШ саясаты бар.
Retry-rate бюджетке сәйкес келеді (10-15% ≤), оқыс оқиғалар кезінде жарылыс жоқ.
CB бүкіл пул құлағанға дейін іске қосылады; каскадтық істен шығулар жоқ.
Трейдерлер/hedging әрекеттерін көрсетеді; p99 шыңдалған кезде тұрақты.
Канареялық релиздер ретрайлардың «ұқыпты» профилін пайдаланады.

16) Конфигурацияның қысқа мысалдары

Resilience4j YAML (Spring Boot, идея):
yaml resilience4j:
circuitbreaker:
instances:
psp:
slidingWindowType: COUNT_BASED slidingWindowSize: 100 minimumNumberOfCalls: 50 failureRateThreshold: 50 waitDurationInOpenState: 30s permittedNumberOfCallsInHalfOpenState: 5 retry:
instances:
psp:
maxAttempts: 2 waitDuration: 200ms enableExponentialBackoff: true exponentialBackoffMultiplier: 2. 0 retryExceptions:
- java. net. SocketTimeoutException
- java. io. IOException
Envoy rate-limit (идея фрагменті):
yaml rate_limits:
- actions:
- generic_key: { descriptor_value: "api. payments" }

17) Қорытынды

Тұрақтылық - бұл пән: таймауттар → ретраи (джиттермен және бюджетпен) → Circuit Breaker + bulkhead/квоталар және жылдам бас тарту. Периметрді (outlier-ejection) теңшеңіз, RED/CB/Retry дашбордтарын іліңіз, іспеттілік саясатын белгілеңіз және бизнес-SLI туралы ұмытпаңыз. Сонда қысқаша іркілістер байқалмайды, ал шынайы оқиғалар каскадты құлдырауға айналмайды.

Contact

Бізбен байланысыңыз

Кез келген сұрақ немесе қолдау қажет болса, бізге жазыңыз.Біз әрдайым көмектесуге дайынбыз!

Интеграцияны бастау

Email — міндетті. Telegram немесе WhatsApp — қосымша.

Сіздің атыңыз міндетті емес
Email міндетті емес
Тақырып міндетті емес
Хабарлама міндетті емес
Telegram міндетті емес
@
Егер Telegram-ды көрсетсеңіз — Email-ге қоса, сол жерге де жауап береміз.
WhatsApp міндетті емес
Пішім: +ел коды және номер (мысалы, +7XXXXXXXXXX).

Батырманы басу арқылы деректерді өңдеуге келісім бересіз.