バックオフとリトライ
バックオフして再試行します
「バックオフとリトライ」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
リトライする理由
一時的な障害、タイムアウト、接続切断、一時的な503などは、2回目の試行で成功することがよくあります。リトライによって、不安定な処理を呼び出し元に負担をかけず、信頼性の高い処理にできます。
単純なリトライは危険
タイトなループで直ちにリトライすると、問題を抱えたサービスに大量のリクエストを送り続け、リトライストームを引き起こす可能性があります。試行の間には遅延が必要で、その遅延は徐々に長くするべきです。
指数バックオフ
指数バックオフでは、失敗するたびに待機時間を2倍にします。100ms、200ms、400ms、800msのように増加します。これにより、下流のサービスが復旧するための時間を確保できます。
delay := 100 * time.Millisecond
for attempt := 0; attempt < 5; attempt++ {
// try, on failure:
time.Sleep(delay)
delay *= 2
}ジッターの追加
多くのクライアントが同じタイミングでバックオフすると、全クライアントが同時にリトライする、いわゆるthundering herdが発生します。ジッターによって各遅延を少しずつランダム化し、リトライのタイミングを分散させます。
jitter := time.Duration(rand.Int63n(int64(delay) / 2))
time.Sleep(delay + jitter)遅延の上限設定
指数的な増加によって、待機時間はすぐに非常に長くなります。試行の間に何分も待たずに済むよう、遅延に最大値を設定します。
if delay > 2*time.Second {
delay = 2 * time.Second
}試行回数の制限
試行回数には必ず上限を設けます。上限に達したら最後のエラーを返し、無限にリトライするのではなく、呼び出し元が次の対応を判断できるようにします。
冪等な処理だけをリトライする
リトライが安全なのは、同じ操作を2回実行しても問題が起きない場合だけです。GETは冪等ですが、カードに課金する冪等でないPOSTを無条件にリトライしてはいけません。必要に応じて冪等性キーを使用します。
完全なバックオフリトライ
このプログラムは、2回失敗した後に成功する関数をリトライし、そのたびに遅延時間を2倍にします。標準ライブラリだけを使用しています。
package main
import (
"errors"
"fmt"
"time"
)
func flaky(attempt int) error {
if attempt < 2 {
return errors.New("temporary failure")
}
return nil
}
func main() {
delay := 50 * time.Millisecond
var err error
for attempt := 0; attempt < 5; attempt++ {
err = flaky(attempt)
if err == nil {
fmt.Println("succeeded on attempt", attempt)
return
}
fmt.Printf("attempt %d failed, waiting %v\n", attempt, delay)
time.Sleep(delay)
delay *= 2
}
fmt.Println("gave up:", err)
}contextへの対応
contextをリトライループに渡し、スリープ中にctx.Done()をselectします。これにより、キャンセルまたはタイムアウトした呼び出し元は、直ちにリトライを停止できます。
select {
case <-ctx.Done():
return ctx.Err()
case <-time.After(delay):
}エラーの判別
すべてのエラーがリトライ可能とは限りません。400 Bad Requestは何度試しても失敗します。エラーまたはステータスコードを調べ、タイムアウト、429、5xxなど一時的な障害の場合にだけリトライします。
サーキットブレーカー
障害が続く場合、サーキットブレーカーは各呼び出しをリトライする代わりに、クールダウン期間中のリクエスト送信を停止します。明らかに停止している依存先を保護することで、バックオフを補完します。
クイックチェック
バックオフに関する知識を確認しましょう。
振り返り
バックオフとリトライについて学びました。
- 指数バックオフは、失敗するたびに遅延を2倍にする
- ジッターによって同期したリトライストームを防ぐ
- 遅延に上限を設け、試行回数を制限する
- 冪等な処理、またはリトライ可能なエラーの場合だけリトライする
- キャンセルに対応するためcontextを尊重する
よくある質問
「バックオフとリトライ」レッスンは無料ですか?
はい。「バックオフとリトライ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。
「バックオフとリトライ」で何を学びますか?
バックオフして再試行します ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Go Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「バックオフとリトライ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このGo Academyレッスンでコードを書いて実行できますか?
はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。