代表的な面接トピック

バックエンド面接:実用的な 429 および Retry-After コントラクトの設計

バックエンド普通
Offer.cc 編集チーム公開日 更新日

質問

あるパブリック API は、テナント、アカウント、エンドポイントごとにリクエストを制限しています。クライアントは 429 の直後に再試行することが多く、リカバリを遅らせており、SDK 間でも Retry-After の解釈が異なっています。サーバーのレスポンス規約とクライアントの動作を設計してください(いつ再試行すべきか、待機時間の計算方法、リトライストームの回避方法、正しく機能していることを証明するメトリクスを含む)。

プロンプトと対象範囲

これは単なる Redis カウンターの実装ではなく、レート制限のプロトコル境界をテストするものです。RFC 6585 では、一定期間内の過剰なリクエストに対して 429 を定義し、Retry-After を許可しています。RFC 9110 では秒数と HTTP 日時を定義しています。これらのセマンティクスを、クライアントが安全に実行できる動作へと変換してください。

面接官が評価しているポイント

  • 誰が制限されており、いつリカバリ可能なのかを説明する制限キー、ウィンドウ、クォータ、レスポンスフィールド。
  • 一貫した 429 ボディ、Retry-After、リクエスト ID、安全なクォータの詳細。
  • クライアント側での秒数または日時のパース、ジッター、デッドライン、試行回数バジェット。
  • 非冪等な書き込み、非同期ジョブ、ネットワークタイムアウトに対する再試行の境界。
  • 制限ヒット、リカバリ時間、再試行増幅率、最終的な成功に関するメトリクス。

推奨される回答構成

制限のディメンションとエラー分類を定義します。429 レスポンスと Retry-After のルールを示します。クライアントはヘッダー、リクエストタイプ、ローカルバジェットを使用して、待機、中止、または非同期処理への切り替えを行います。すべての再試行には上限付きのエクスポネンシャルバックオフとジッターを使用します。最後に、ゲートウェイ、アプリケーション、SDK、ビジネス運用の責務とフォールトインジェクションテストについて述べます。

ディープダイブ:レスポンスから再試行まで

制限を説明可能にする

制限のキーは、テナント、クレデンシャル、IP、エンドポイント、またはグローバルリソース単位で設定します。安定したエラータイプ、リクエスト ID、安全な理由を返します。複数のリミッターが発動した場合は、他のテナントのクォータを開示することなく、既知の最も長い待機時間を使用します。

Retry-After を正しく生成する

遅延(秒数)は最低何秒待機すべきかを意味し、HTTP 日時はリカバリ時刻を意味します。内部ウィンドウはモノトニッククロックで計算し、切り上げて上限を設定します。日時はクロックスキューやプロキシの影響を受ける可能性があるため、クライアント側には依然として最小待機時間とジッターが必要です。

クライアントでのパースとバックオフ

まず Retry-After を優先します。ヘッダーが存在しないか無効な場合は、上限付きのエクスポネンシャルバックオフを使用します。各論理リクエストに全体のデッドラインと試行回数バジェットを設定します。多数のタスクが一斉に再開しないよう、共有キューやトークンバジェットを通じて並行処理を調整します。

冪等性の境界を尊重する

GET、HEAD、および明示的に冪等な PUT や DELETE は通常、再試行可能です。POST には冪等性キーと、それに対応するサーバーセマンティクスが必要です。実行後にレスポンスが失われた場合は、2 回目の副作用を発生させるのではなく、ステータスを照会するか同じキーを再利用します。

エラーだけでなくリカバリを監視する

制限ディメンション、429 カウント、Retry-After の分布、クライアントの待機時間、再試行増幅率、最終的な成功、中止を記録します。SDK バージョンやテナントごとにセグメント化し、即時の再リクエストと正当なトラフィック増加を区別します。

回答例

「私ならテナント、クレデンシャル、エンドポイントごとにレート制限を行い、安定したエラータイプ、リクエスト ID、安全な理由、Retry-After を返します。サーバーはモノトニックウィンドウ遅延を計算し、切り上げて上限を設定します。SDK はまず Retry-After をパースし、それ以外の場合はジッター付きエクスポネンシャルバックオフを使用します。各論理リクエストにはデッドラインと試行制限を設けます。GET は再試行可能とし、POST には冪等性キーまたはステータス照会を必須とします。429、待機時間の分布、再試行増幅率、最終的な成功、中止を監視し、同期マルチクライアントテストを実行してスムーズなリカバリを検証します。」

よくある障害パターンと対策

  • すべての障害を再試行する → ステータス、メソッドのセマンティクス、エラータイプによって分類する。
  • Retry-After の形式を無視する → 秒数と HTTP 日時の両方をサポートし、無効な値は安全に破棄する。
  • スレッドごとに即時再試行する → バジェット、キュー、ジッターを共有する。
  • POST が冪等であると決めつける → 冪等性キー、ステータス照会、または明示的な再試行不可の結果を使用する。
  • 429 のカウントのみを監視する → 待機時間、増幅率、最終的な成功、中止を測定する。

評価基準とセルフチェック

優れた回答には、制限キー、429 のセマンティクス、Retry-After の生成とパース、ジッター付きバックオフ、デッドライン、冪等性、並行処理の調整、安全なクォータの詳細、コンポーネントの責務分担、検証メトリクスが含まれます。

確認事項:クライアントはいつリカバリ可能か把握できていますか? クロックのズレがある場合はどうなりますか? ヘッダーが存在しない場合はどうしますか? 再試行によって副作用が重複する可能性はありませんか? 並行タスクはどのように分散されますか? リカバリが改善されたことを何が証明しますか?

フォローアップと発展課題

Retry-After は秒数と日時のどちらを使用すべきですか?

どちらも有効な HTTP 形式です。秒数は短いウィンドウに適しており、クロックのズレを回避できます。日時は既知のリカバリポイントを表現できます。サーバーの出力には一貫性を持たせつつ、SDK のパース処理では両方に対応し、期限切れの値を適切に処理できるようにします。

ゲートウェイとアプリケーションの両方が制限をかける場合、どちらの待機時間を返しますか?

クライアントに見せる待機時間は、既知のすべての制限をカバーするべきであり、通常はリクエスト ID とともに最も長い値を返します。内部テレメトリでは各レイヤーを記録し、ゲートウェイでの拒否が誤ってアプリケーションのせいにされないようにします。

クライアントは Retry-After なしで再試行できますか?

メソッドとエラーのセマンティクスがそれを許可し、デッドラインが残っており、ローカルのバックオフバジェットが十分にある場合に限られます。上限付きのジッターバックオフを使用してください。再試行不可能な書き込みに対しては、照会可能な状態または明示的な失敗を返します。

リトライストームはどのようにテストしますか?

多数のクライアントを同期させて 429 を発生させ、無効なヘッダー、クロックスキュー、接続タイムアウト、リカバリジッターを注入します。到達曲線、増幅率、リカバリ時間、最終的な成功率を観察します。

公開情報ソース

関連する質問