GH GambleHub

サーキットブレーカとリトリート

サーキットブレーカーとレトライ

1)なぜそれを必要とします

ネットワークは信頼できない:レイテンシの脈動、ノードの落下、制限に達します。リトレイは短期的な障害から保存され、Circuit Breakerはカスケード障害や自己DDoSからシステムを保護します。正しいタイムアウトと限界との組み合わせは、SLOを保持し、尾の遅延と「ナイン」の価格を安定させます。

2)基本原則

最初のタイムアウト、その後、後退し、サーキットブレーカー。
Retraim idempotent operations (GET、 secure POST/PUT with idempotent key)。
リトレイ予算を割り当てる:ルートごとに元のRPSの10-15%を≤します。
失敗のローカライズ:隔壁(個別のプール/クォータ)+レート制限。
劣化中-高速障害(フェイルファスト)、優雅な劣化/スタブ。

3)リトレイセマンティクス

いつ退却するか

一時エラー:タイムアウト、5xx、ネットワーク利用不可、429 ('Retry-After'の後)。
あなたは取り戻すことはできません:明らかなビジネスエラー(4xx ≠ 429)、 idempotenceなしの副作用(キーなしでの支払い)。

戦略

指数関数バックオフ+ジッタ(フルまたは偶数):リトレースの群れを滑らかにします。
最大の試み:1-2(まれに3)-より多くは通常有害です。
予算:サービスごとにグローバルリトレイカウンター/秒、リクエストごとに「再試行トークン」。
ヘッジング(まれ):t-quantle (p95)の後のリクエストの平行二重-厳密にはidempotent readsに対してのみ。

疑似コードのバックオフ+ジッタ:
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)周囲の統合(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障害/再試行、圧縮例):
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(コンテキストの締め切り+バックオフ):
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メトリクス:Rate、 Error、 Duration (p50/p95/p99)。
CBメトリクス:ステータス(オープン/ハーフオープン)、オープニングレート、リクエストの欠落/拒否。
再トレイ:試行/リクエスト、再試行レート、燃えたトークン。
周囲:outlier-ejection、 ejection-rate。
トレース:注釈'retry_attempt'、' cb_state'、'hedged=true'、'trace_id'。

12)アーキテクチャの統合

各クリティカル上流のバルクヘッド+CB。
キュー/asynchron:クレイジーなタイムアウトの代わりに長い操作のために。
キャッシュ/スタブ:フェイルオープン時の重要でない機能の場合。
Autoscale:悪い後退を補っていません-最初に嵐を止めてください。

13)アンチパターン

タイムアウトのないリトレイ→フリーズした接続とプールの枯渇。
非idempotentトランザクション(ダブルライトオフ)を繰り返します。
キャップとジッタなしの無限指数成長。
単一のCBからすべてのアップストリームへ→製品全体へのドラッグアンドドロップ障害。
429/' Retry-After'を無視します。
クライアントのタイムアウトは、アップストリームのタイムアウトよりも長い(またはまったくない)。
レトラでビジネスエラーを「扱う」。

14)実装チェックリスト(0-30日)

0-7日

ルートとそのidempotencyを特定します。
タイムアウト(接続/読み取り/全体)を設定し、最小リトレイ(× 1)とデフォルトのCBを有効にします。
メイン上流のプール/クォータ(隔壁)を分離します。

8-20日

ジッタとグローバルリトレイの予算、再試行率アラートが含まれます。
低プリオ機能の境界、高速障害のアウトリエ放出を設定します。
RED+CB/再試行ダッシュボード、タグ付きトレイル。

21-30日

カナリアリトレイプロファイル(試行回数が少ない)、ゲームデー「アップストリームスロー/フラップ」。
ドキュメントポリシー:who/what retraces、 limits、 exceptions。
p95/p99とタイムアウトを目ではなくデータに従って確認します。

15)成熟度の指標

ルートの100%はタイムアウトとドキュメント化されたリトレイ/NEポリシーを持っています。
再試行率は予算(≤ 10-15%)に適合し、インシデントにはスパイクはありません。
プール全体が落ちる前にCBが発砲します。カスケード障害はありません。
トレイルは、試行/ヘッジを表示します。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)結論

持続可能性は規律です:タイムアウト→リトリート(ジッタと予算)→サーキットブレーカー+隔壁/クォータと迅速な拒絶。周囲を設定し(外側からの取り出し)、RED/CB/Retryダッシュボードをハングアップし、idempotencyポリシーを修正し、ビジネスSLIを忘れないでください。その後、簡単な失敗は目に見えないままになり、実際の事件はカスケードフォールに変わりません。

Contact

お問い合わせ

ご質問やサポートが必要な場合はお気軽にご連絡ください。いつでもお手伝いします!

Telegram
@Gamble_GC
統合を開始

Email は 必須。Telegram または WhatsApp は 任意

お名前 任意
Email 任意
件名 任意
メッセージ 任意
Telegram 任意
@
Telegram を入力いただいた場合、Email に加えてそちらにもご連絡します。
WhatsApp 任意
形式:+国番号と電話番号(例:+81XXXXXXXXX)。

ボタンを押すことで、データ処理に同意したものとみなされます。