Circuit Breaker жана Retray
Circuit Breaker жана Retray
1) Эмне үчүн керек
Тармактар ишенимдүү эмес: латенттүүлүк кагат, түйүндөр түшөт, лимиттерге жетишилет. Retrailer кыска мөөнөттүү бузулуулардан куткарат, ал эми Circuit Breaker системаны каскаддык бузулуулардан жана "өзүн-өзү DDoS" коргойт. Туура таймауттар жана лимиттер менен айкалышы SLO сактайт, куйрук кечигүүлөрүн жана "тогуздуктардын" баасын турукташтырат.
2) Негизги принциптер
Биринчи таймауттар, андан кийин ретрациялар, андан кийин Circuit Breaker.
retraim гана idempotent иш (GET, коопсуз POST/PUT idempotent ачкычы менен).
Retrains бюджетти бөлүп: ≤ маршруту боюнча баштапкы RPS 10-15%.
Баш тартууну локалдаштыруу: bulkhead (өзүнчө бассейндер/квоталар) + rate-limit.
Деградацияда - тез бузулуу (fail-fast), graceful-degradation/штепсель.
3) Ретрайлардын семантикасы
Качан ретрациялоо
Транзиттик каталар: timeouts, 5xx, тармак жеткиликсиздиги, 429 (кийин 'Retry-After').
Ретрациялоо мүмкүн эмес: ачык-айкын бизнес каталар (4xx ≠ 429), демпотенттиги жок side-effects (ачкычы жок төлөм).
Стратегиялар
Exponential backoff + jitter (толук же бир калыпта): retrains үйүрүн жылмакай.
Max attempts: 1-2 (сейрек 3) - көп, адатта, зыяндуу.
Budget: кызмат жана per-request "retry tokens" үчүн глобалдык retrai/сек эсептегич.
Hedging (сейрек): T-Quantiles кийин параллелдүү эки суроо (p95) - катуу idempotent окуу үчүн гана.
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-fich бирикмелердин өзүнчө пулдар.
In-flight боюнча квоталар; ашыкча - тез баш тартуу.
жетишсиздик менен - төмөн артыкчылык менен phich деградация (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) Retrains жана SLO бюджети
retry tokens киргизүү: ар бир retrai токен сарптайт; бассейн чектелген.
error-budget менен байланыштырыңыз: босогодон жогору бурн-rate менен - ретрацияны өчүрүп, CBны тез-тез ачып, деградацияны күйгүзөбүз.
Канареялык релиздер: Канареяларда аракетти жана токендерди азайтыңыз.
10) Hedging (этият)
Жеңилгенди жокко чыгаруу менен p95 мөөнөтүнөн кийин кошумча суроо-талапты ишке киргизиңиз.
Гана окуу жана "коопсуз" idempotent иш үчүн; үлүшүн чектөө (≤ 1-5%).
Апстримге жүктүн өсүшүнө көз салыңыз.
11) Байкоо
Rate, Error, Duration (p50/p95/p99).
CB-метрика: абалы (open/half-open), ачылыш жыштыгы, сагынып/четке суроо.
Retrays: attempts/request, retry-rate, өрттөлгөн токендер.
Периметри: outlier-ejection, ejection-rate.
Traces: аннотация 'retry _ attempt', 'cb _ state', 'hedged = true', ыргытып 'trace _ id'.
12) Архитектура менен интеграция
Bulkhead + CB боюнча ар бир критикалык агым.
Кезек/асинхрон: акылдуу убакыт ордуна узак иш үчүн.
Кэш/өчүргүчтөр: fil-open боюнча сын эмес fich үчүн.
Autoscale: жаман retra ордун толтурбайт - биринчи "бороон" токтотуу.
13) Анти-үлгүлөрү
Таймаутсуз ретрациялар → "илинип калган" коннектилер жана пулдун түгөнүшү.
Демпотенттик эмес операцияларды кайталоо (кош эсептен чыгаруу).
Чексиз экспоненциалдык өсүш жок cap жана jitter.
Бардык апстримдер үчүн бирдиктүү CB → бүт продукт боюнча ийгиликсиз сүйрөп.
Көңүл бурбоо 429/' Retry-After '.
Кардардын таймауты апстримге караганда узун (же такыр жок).
"Дарылоо" бизнес каталар retrains.
14) киргизүү чек-тизмеси (0-30 күн)
0-7 күн
Жолдорду жана алардын демпотенттигин аныктаңыз.
Таймауттарды белгилөө (connect/read/overall), минималдуу ретраларды (× 1) жана демейки CBди күйгүзүү.
Негизги агымдар үчүн пулдарды/квоталарды бөлүңүз.
8-20 күн
Jitters жана дүйнөлүк бюджетти retry-rate боюнча алерттерди камтыйт.
периметри боюнча outlier-ejection орнотуу, low-prio fich үчүн тез баш тартуу.
Dashboard RED + CB/Retry, белгилер менен соода.
21-30 күн
Канарейка профилдери (азыраак аракет), game-day "жай агымы/флапер".
саясат документтештирүү: ким/эмне retrait, чектер, өзгөчөлүктөр.
p95/p99 жана убакыт карап эмес, көз.
15) Жетилүү метрикасы
100% каттамдардын таймауттары жана документтештирилген ретра/SV саясаты бар.
Retry-rate бюджетке туура келет (≤ 10-15%), эч кандай окуялар боюнча жарылуулар.
CB бүт көлмөгө чейин иштейт; каскаддык мүчүлүштүктөр жок.
Tracks аракет/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/квота жана тез баш тартуу. Perimetre (outlier-ejection), RED/CB/Retry дашбордддорун илип, демпотенттик саясатын чечүү жана бизнес SLI жөнүндө унутпа. Ошондо кыска мүчүлүштүктөр байкалбай калат, ал эми чыныгы окуялар каскаддык төмөндөөгө айланбайт.