Қатъи гардиш ва ақибнишинӣ
Қатъи гардиш ва ретрай
1) Чаро ба шумо лозим аст
Шабакаҳо беэътимод мебошанд: пульсатҳои дермонӣ, гиреҳҳо меафтанд, маҳдудиятҳо ба даст меоянд. Рафторҳо аз хатогиҳои кӯтоҳмуддат наҷот дода мешаванд ва Circuit Breaker системаро аз хатогиҳои тасодуфӣ ва худидоракунии DD муҳофизат мекунад. Якҷоя бо танаффуси дуруст ва маҳдудиятҳо SLO-ро нигоҳ медорад, таъхирҳои дум ва нархи "nines" -ро мӯътадил мекунад.
2) Принсипҳои асосӣ
Вақти аввал, баъд ақибнишинӣ, баъд Circuit Breaker.
Retraim танҳо амалиёти idempotent (GET, POST/PUT бо калиди idempotent).
Буҷаи бозпардохтро ҷудо кунед: ≤ 10-15% RPS-и аслӣ дар як масир.
Маҳаллисозии нокомӣ: болопӯш (ҳавзҳои алоҳида/квотаҳо) + меъёри маҳдудият.
Ҳангоми таназзул - нокомии зуд (нокомӣ зуд), деградатсияи зебо/стуб.
3) Семантикаи ретрей
Кай бояд ақибнишинӣ кард
Хатогиҳои муваққатӣ: танаффус, 5xx, дастнорас будани шабака, 429 (пас аз 'Retry-After').
Шумо наметавонед бозпас гиред: хатогиҳои ошкорои тиҷорат (4xx ≠ 429), таъсири тарафҳо бе аблаҳӣ (пардохт бе калид).
Стратегияҳо
Рафти экспоненсиалӣ + ҷиттер (пурра ё ҳатто): тӯдаи кашишҳоро ҳамвор мекунад.
Кӯшишҳои макс: 1-2 (кам 3) - бештар одатан зарароваранд.
Буҷа: муқовимати ҷаҳонӣ барои як хидмат ва ҳар як дархост "нишонаҳои такрорӣ".
Хеджинг (нодир): дучанд параллели дархост пас аз t-quantile (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) Вақтсанҷӣ ва "нокомии зуд"
Вақти истироҳати мизоҷон <вақти болооб: то ки дархостҳои "зомби" ҷамъ нашаванд.
Делите: танаффусро пайваст кунед, вақти хондан, мӯҳлати умумӣ.
Вақтсанҷи огоҳона: мақсад барои p95/p99 + маржаи хурд.
Як майдони мӯҳлати муқаррариро истифода баред (масалан, 'мӯҳлати ниҳоии GRPC') ва онро ба занҷир партоед.
5) Шикастани гардиш: Чӣ гуна он кор мекунад
Давлатҳо:- Пӯшида: ҳаракат мегузарад, хатогиҳо/таъхирро ҳисоб мекунад.
- Кушода: фавран рад мекунад (ё ҷавоби эҳтиётӣ).
- Ним-кушода: дархостҳои санҷишӣ; агар муваффақ бошад, пӯшида мешавад.
- Хатогиҳо/танаффусҳо аз X% барои як тиреза N дархостҳо/сонияҳо ё p99 аз ҳадди ниҳоӣ зиёдтаранд.
- Омори ғелонда ва ҳаҷми ҳадди аққал мувофиқ аст (масалан, ≥ 50 дархост).
6) Булкхед, квотаҳо ва тақсим ва забт кардан
Ҳавзҳои ҷудогонаи пайвасти ҳар як боло ва ҳар як хусусият.
Квотаҳо барои дархостҳои парвоз; зиёдатӣ - радкунии зуд.
Дар ҳолати норасоӣ - таназзули парчамҳои хусусӣ.
7) Интегратсияи периметрӣ (Фиристанда/Истио/Нгинкс)
Фиристанда (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
Истио (хатогии виртуалӣ/такрорӣ, мисоли фишурдашуда):
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 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() }
Гиреҳ. 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) Буҷаи Retray ва SLO
Нишонаҳои такрорӣ: Ҳар як бозсозӣ аломатро сарф мекунад; ҳавз маҳдуд аст.
Бо буҷаи хатогӣ шарик шавед: агар меъёри сӯзондан аз ҳадди ниҳоӣ болотар бошад, бозхаридҳоро хомӯш кунед, CB-ро зудтар кушоед, таназзулро фурӯзон кунед.
Варақаҳои канарӣ: Дар канарейкаҳо кӯшишҳо ва нишонаҳоро кам кунед.
10) Хеджинг (эҳтиёт)
Пас аз мӯҳлати p95 дархости иловагиро иҷро кунед, зиёнкорро бекор кунед.
Танҳо барои амалиётҳои номатлуб ва "бехатар"; саҳмро маҳдуд мекунад (≤ 1-5%).
Афзоиши сарбориро дар болооб тамошо кунед.
11) Мушоҳидакорӣ
Нишондиҳандаҳои RED дар тӯли масирҳо: Суръат, Хатогӣ, Давомнокӣ (p50/p95/p99).
Нишондиҳандаҳои CB: вазъ (кушода/нисфи кушода), сатҳи кушодашавӣ, дархостҳои пазмоншуда/радшуда.
Бозсозӣ: кӯшишҳо/дархостҳо, меъёри такрорӣ, нишонаҳои сӯхташуда.
Периметр: берунӣ-ejection, ejection-rate.
Нишонаҳо: шарҳи 'retry _ state', 'cb _ state', 'hedged = true', рехтани 'trace _ id'.
12) Интегратсияи меъморӣ
Bulkhead + CB барои ҳар як муҳим дар болооб.
Навбатҳо/асинхрон: барои амалиёти тӯлонӣ ба ҷои танаффуси девона.
Кэш/пояҳо: барои хусусиятҳои ғайримуқаррарӣ ҳангоми кушодани он.
Autoscale: Оё ақибнишинии бадро ҷуброн намекунад - аввал тӯфонро қатъ кунед.
13) Анти-намунаҳо
Рафтаҳо бидуни танаффус → пайвастҳои яхкардашуда ва фарсудашавии ҳавзҳо.
Амалиётҳои ғайримуқаррариро такрор кунед (аз ҳисоб баровардани дубора).
Афзоиши беохири экспоненсиалӣ бе cap ва jitter.
Як CB ба тамоми болооб § кашед ва нокомиро ба тамоми маҳсулот партоед.
Нодида гирифтани 429/' Retry-After '.
Мӯҳлати муштарӣ нисбат ба вақти болооб (ё тамоман нест) дарозтар аст.
Хатогиҳои тиҷоратро "муносибат" кунед.
14) Рӯйхати санҷиши амалисозӣ (0-30 рӯз)
0-7 рӯз
Муайян кардани хатсайрҳо ва номутобиқатии онҳо.
Вақтсанҷӣ (пайвастшавӣ/хондан/умумӣ) барпо кунед, бозхонии минималӣ (× 1) ва пешфарзии CB-ро даргиронед.
Ҳавзҳо/квотаҳоро (болопӯшро) барои болооби асосӣ ҷудо кунед.
8-20 рӯз
Дохил кардани буҷаи ҷиттер ва глобалии бозсозӣ, огоҳиҳои такрорӣ.
Танзими баромади периметри, нокомии зуд барои хусусияти паст-prio.
Панелҳои RED + CB/Retry, пайраҳаҳои барчасп.
21-30 рӯз
Профилҳои бозгашти канарӣ (кӯшиши камтар), бозии рӯзона "оҳиста/боло".
Сиёсати ҳуҷҷат: кӣ/чӣ мегирад, маҳдудиятҳо, истисноҳо.
P95/p99 ва танаффусро аз рӯи маълумот дида бароед, на аз рӯи чашм.
15) Нишондиҳандаҳои камолот
100% хатсайрҳо танаффус ва сиёсати ҳуҷҷатгузории бозгашт/NE доранд.
Меъёри такрорӣ ба буҷа мувофиқ аст (≤ 10-15%), дар ҳодисаҳо ягон хӯшае нест.
CB-ҳо пеш аз афтидани тамоми ҳавз оташ мегиранд; ҳеҷ гуна нокомии тасодуфӣ.
Роҳҳо кӯшишҳо/ҳимояро нишон медиҳанд; p99 дар қуллаҳо устувор аст.
Варақаҳои канарӣ профили бозгашти "бодиққат" -ро истифода мебаранд.
16) Намунаҳои конфигуратсияи кӯтоҳ
Resilience4j YAML (Бут баҳор, идея):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
Лимити меъёри фиристанда (порчаи ғоя):
yaml rate_limits:
- actions:
- generic_key: { descriptor_value: "api. payments" }
17) Хулоса
Устуворӣ як интизом аст: танаффусҳо → ақибнишинӣ (бо ҷиттер ва буҷа) → Circuit Breaker + bulkhead/квотаҳо ва радкунии зуд. Периметри (берунӣ) насб кунед, панелҳои RED/CB/Retry-ро овезон кунед, сиёсати idempotency-ро ислоҳ кунед ва дар бораи тиҷорати SLI фаромӯш накунед. Он гоҳ нокомиҳои кӯтоҳ ноаён боқӣ хоҳанд монд ва ҳодисаҳои воқеӣ ба афтиши тасодуфӣ табдил нахоҳанд ёфт.