エラー処理とリトライロジック
ステータスコードを確認し、リトライを実装します。
「エラー処理とリトライロジック」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
HTTP エラーは Go のエラーではない
HTTP 404 や 500 のステータスは Go のエラーではありません。http.Client.Do は、有効な HTTP レスポンスであればエラーを nil として返します。resp.StatusCode を明示的に確認してください。
エラーをラップする
fmt.Errorf("operation: %w", err) を使ってコンテキスト付きでエラーをラップすると、呼び出し側で errors.Is / errors.As を使って原因を調べられます。
if err != nil {
return fmt.Errorf("fetch users: %w", err)
}再試行可能なエラーと再試行できないエラー
再試行するエラー:ネットワークタイムアウト、429 Too Many Requests、503 Service Unavailable。再試行しないエラー:400 Bad Request、401 Unauthorized、404 Not Found。再試行しても解決しません。
指数バックオフ
障害が発生しているサーバーへの負荷を減らすため、再試行するたびに待ち時間を長くします。簡単な実装例:
for i := 0; i < maxRetries; i++ {
resp, err := client.Do(req)
if err == nil && resp.StatusCode < 500 { break }
time.Sleep(time.Duration(math.Pow(2, float64(i))) * time.Second)
}ジッター
複数のクライアントが同時に再試行するのを防ぐため、バックオフにランダムなジッターを加えます(サンダリングハード)。
wait := time.Duration(math.Pow(2, float64(i)))*time.Second + time.Duration(rand.Intn(1000))*time.MillisecondRetry-After ヘッダー
429 レスポンスには、多くの場合 Retry-After ヘッダーが含まれます。固定のバックオフを使うのではなく、この値を解析して従ってください。
retryAfter := resp.Header.Get("Retry-After")
if secs, err := strconv.Atoi(retryAfter); err == nil {
time.Sleep(time.Duration(secs) * time.Second)
}コンテキストに対応した再試行
再試行するたびにコンテキストを確認し、リクエストがキャンセルされていたら再試行を停止してください。
for i := 0; i < maxRetries; i++ {
if ctx.Err() != nil { return nil, ctx.Err() }
// attempt
}カスタムエラー型
ステータスコードとボディを保持する型付き HTTP エラーを定義すると、呼び出し側で再試行するかどうかを細かく判断できます。
type HTTPError struct {
Status int
Body string
}
func (e *HTTPError) Error() string { return fmt.Sprintf("HTTP %d: %s", e.Status, e.Body) }ライブラリの選択肢
本番環境の再試行処理には、バックオフポリシー、最大再試行回数、コンテキスト対応を設定できる hashicorp/go-retryablehttp や cenkalti/backoff の利用を検討してください。
冪等性キー
POST リクエストを再試行する場合は、冪等性キー(UUID)をヘッダーに含めてください。これによりサーバーは再試行を重複排除し、リソースを重複して作成せずに同じ結果を返せます。
サーキットブレーカー
サーキットブレーカーは失敗率を追跡し、失敗しているサービスへのリクエスト送信をクールダウン期間中停止します。sony/gobreaker などのライブラリがこのパターンを実装しています。
クイックチェック
指数バックオフにジッターを追加する必要があるのはなぜですか?
振り返り:エラー処理と再試行
主なポイント:
- resp.StatusCode を確認する。HTTP エラーは Go のエラーではない
- 429、503、ネットワークタイムアウトでは再試行し、4xx のクライアントエラーでは再試行しない
- 指数バックオフとジッターにより、サンダリングハードを防ぐ
- 再試行する前に必ずコンテキストを確認する
よくある質問
「エラー処理とリトライロジック」レッスンは無料ですか?
はい。「エラー処理とリトライロジック」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- HTTPリクエストの送信
- タイムアウトとヘッダーの設定
- JSONレスポンスのデコード
- エラー処理とリトライロジック