GH GambleHub

Circuit Breaker和Retrai

Circuit Breaker and Retrai

1)為什麼需要它

網絡不可靠:潛伏脈沖,節點下降,達到極限。Retrai可以避免短暫的故障,而Circuit Breaker可以保護系統免受級聯故障和「samo-DDoS」的影響。與正確的計時器和限制相結合,可以保持SLO,穩定尾部延遲和「九」價格。

2)基本原則

首先是taymauts,然後是retrai,然後是Circuit Breaker。
僅恢復偶數操作(GET,具有偶數鍵的安全開機/PUT)。
撥出轉發預算:每條路線≤原始RPS的10-15%。
本地化故障:bulkhead(分離池/配額)+rate-limit。
降解-快速故障(fail-fast), graceful-degradation/存根。

3)Retrae語義

何時回蕩

過境錯誤:timeouts,5xx,網絡不可用,429(在「Retry-After」之後)。
您不能轉發:顯式業務錯誤(4 xx ≠ 429), side-effects沒有等效性(無鑰匙付款)。

策略

Exponential backoff+jitter(完整或均勻):平滑背包。
Max attempts:1-2(很少3)-通常更有害。
Budget:全球每種服務的轉發/秒計數器和per-request 「retry tokens」。
Hedging(很少):t-quantili (p95)後並行查詢復制-僅用於嚴格等效閱讀。

偽代碼backoff+jitter:
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)Taymauts和「快速拒絕」

Client timeout <upstream timeout:不要挖掘「僵屍」查詢。

Делите: connect timeout, read timeout, overall deadline.

Tail-aware定時器:我們瞄準p95/p99+少量庫存。
使用共享的截止日期字段(例如gRPC「截止日期」)並沿著鏈條向下推。

5) Circuit Breaker: 如何工作

狀態:
  • Closed:跳過流量,計算錯誤/潛伏期。
  • 打開:立即發出快速故障(或備用響應)。
  • 半場開放:驗證請求;成功時-關閉。
開口閾值:
  • 錯誤/時間間隔超過了N查詢/秒窗口的X%分數,或高於閾值的p99。
  • 相關的滾動統計數據和最小體積(例如,≥ 50個查詢)。

6)Bulkhead,配額和「分而治之」

上遊和上場連接的分離子彈。
航班查詢配額;更多的是快速拒絕。
在短缺的情況下-低優先級Fitch降解(功能標記)。

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

輸入復古令牌:每個復古花費令牌;池有限。
與error-budget連接:在高於閾值的burn-rate-禁用轉發,更頻繁地打開CB,包括降解。
金絲雀發行版:在金絲雀上,減少嘗試和令牌。

10)起床(小心)

在p95截止日期後觸發附加請求,取消失敗者。
僅用於閱讀和「安全」等效操作;限制份額(≤ 1-5%)。
留意加速負載的增加。

11)可觀察性

路線上的RED度量:Rate、Error、Duration (p50/p95/p99)。
CB度量:狀態(開放/半開放),發現頻率,遺漏/拒絕的請求。
Retrai:attempts/request,retry-rate,燃燒的令牌。
周長:outlier-ejection, ejection-rate。
Traces:註釋「retry_attempt」、「cb_state」、「hedged=true」、「trace_id」。

12)與體系結構集成

Bulkhead+CB對於每個關鍵的應用。
隊列/asinchron:用於長時間操作而不是瘋狂的taymout。
Kesh/存根:對於失誤打開時非關鍵的幻燈片。
Autoscale:不補償不良的撤退-首先停止「風暴」。

13)反模式

沒有Taymout的Retrai →「懸停」的連接和池的耗盡。
重復非偶數操作(雙重註銷)。
無窮大的指數增長,沒有帽子和擠壓器。
單個CB到所有apstrims →將故障拖到整個產品上。
忽略了429/「Retry-After」。
客戶的定時時間比apstrim(或根本沒有)更長。
「治療」回避業務錯誤。

14)實施清單(0-30天)

0-7天

確定路線及其相容性。
設置計時器(connect/read/overall),啟用最小retrai (× 1)和默認的CB。
將基本應用程序的池/配額(bulkhead)分開。

8-20天

包括jitter和retrais的全球預算,alerta按重復率。
在外圍設置直截了當-ejection,快速故障以實現低價。
RED+CB/Retry dashboards,帶標簽的預告片。

21-30天

金絲雀輪廓retrais(嘗試較少),遊戲日「慢速/輕浮」。
記錄政策:誰/什麼是復述,限制,例外。
根據數據而不是眼睛修改p95/p99和taymout。

15)成熟度量

100%的路線都有taymauts和有記錄的retrais/SV政策。
Retry-rate符合預算(≤ 10-15%),事件中沒有激增。
CB的觸發時間比整個池都早。沒有級聯故障。
Traces顯示嘗試/抱怨;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)結論

可持續性是一門學科:taymauts → retrai(帶有抖動和預算的)→ Circuit Breaker+bulkhead/配額和快速豁免。設置外圍(outlier-ejection),掛起RED/CB/Retry行車記錄板,記錄等效性策略,不要忘記業務SLI。然後,短暫的失敗將保持不變,實際事件不會變成級聯下降。

Contact

與我們聯繫

如有任何問題或支援需求,歡迎隨時聯絡我們。我們隨時樂意提供協助!

Telegram
@Gamble_GC
開始整合

Email 為 必填。Telegram 或 WhatsApp 為 選填

您的姓名 選填
Email 選填
主旨 選填
訊息內容 選填
Telegram 選填
@
若您填寫 Telegram,我們將在 Email 之外,同步於 Telegram 回覆您。
WhatsApp 選填
格式:國碼 + 電話號碼(例如:+886XXXXXXXXX)。

按下此按鈕即表示您同意我們處理您的資料。