要点: ALB が急激にスケールアウトするとターゲット登録が一時的に外れ、50X が多発します。Route 53 で 10 台以上の ALB に分散し、ドレイニングとヘルスチェックを調整して安定化しました。NLB のノイジーネイバーは回避できないため、443 接続はエクスポネンシャルバックオフで再試行する以外に現実的な対処はありません。

デフォルト設定のままでは限界があった背景

大規模な性能テストで ALB と NLB の両方が限界に達しました。標準的な AWS 設定でも次の 2 つの障害モードが顕在化しました。

  • ALB のスケールアウト中にターゲットが外れ、テスト中に 50X エラーが噴出した。
  • NLB が未知のテナントと同居しており、443/TLS 接続が大量にタイムアウトした。

この記事ではその症状、観測に使った指標、最終的に採用した対策を共有します。

障害モード 1: ALB スケールアウト中のターゲット喪失

何が起きたか

ピークトラフィックで ALB がスケールアウトを開始すると、AWS 側で ENI が再作成され、ECS タスクがターゲットグループから一時的に外れました。ドレイニング猶予は 300 秒のデフォルト設定では足りず、アクティブなリクエストが宙に浮いて 50X 応答となりました。さらに同時並行でオートスケーリングが負荷を追いかけるため、 churn が増幅しました。

対策のポイント

  1. ALB をシャーディング: 同一構成の ALB を 10 台以上用意し、Route 53 の Weighted レコードで均等にトラフィックを振り分けました。1 台あたりの影響範囲を限定します。
  2. ターゲットグループの専用化: 各 ALB に HTTP/HTTPS のターゲットグループを専用で割り当て、ECS サービスは 1 つのグループだけに登録しました。
  3. ドレイニング猶予の見直し: Deregistration Delay を 900 秒に引き上げ、ECS のヘルスチェック間隔も合わせて、切り替え中のリクエストを安全に排出します。
  4. 事前ウォーミング: テスト前に modify-load-balancer-attributes などで ALB を想定ピークまで手動スケールさせ、突発負荷前にキャパシティを温めます。
  5. ヘルスチェックの SLO: ヘルスチェックのタイムアウトを 5 秒、連続失敗回数を 2 回に調整し、不健全コンテナを素早く退出させます。

観測に使った指標

  • ALB 標準メトリクス (RequestCount, HTTPCode_Target_5XX_Count, TargetResponseTime).
  • スケールイベント中の RegisterTargets / DeregisterTargets を追う CloudTrail。
  • ECS サービスイベント(service ... has begun draining connections)の時系列確認。

障害モード 2: NLB のノイジーネイバーによる 443 タイムアウト

何が起きたか

NLB は基盤ハードウェアを他テナントと共有します。同居テナントが急増し、接続処理能力を占有した結果、こちらの 443/TLS リスナーで接続タイムアウトが頻発しました。AWS サポートはノイジーネイバーであると認識しつつ、即時移設はできないという回答でした。

対策のポイント

  1. エクスポネンシャルバックオフ: アプリケーションの HTTPS クライアントにジッター付きエクスポネンシャルバックオフを導入しました。初回 100ms から 3 秒まで倍増させ、同時再試行の雪崩を防ぎます。
  2. タイムアウトの分離: TLS ハンドシェイクのタイムアウトを 2 秒に短縮し、読み込みタイムアウトは長めに維持して、接続圧迫時に早く失敗・再試行させます。
  3. サーキットブレーカ: タイムアウト率が 5% を超えたらブレーカを開き、新規リクエストを 30 秒止めて負荷を散らします。
  4. リトライの可視化: リトライ回数とレイテンシ分布をカスタムメトリクスで記録し、バックオフの挙動と顧客影響を紐付けます。TCP_Client_Reset_Count のスパイクで顧客影響前にアラートを発火します。

効かない対策

  • NLB の強制スケーリング: NLB は手動スケール機構を持たず、サブネット追加やクロスゾーン有効化でもノイジーネイバーは解決しません。
  • 即時ハードウェア移設: AWS サポートにチケットを出しても時期は保証されません。アプリ側でのリトライ対策が現実的です。

アーキテクチャ概要

Route 53 (weighted records)
  ├─ ALB shard 1 ─ target group A ─ ECS service payments
  ├─ ALB shard 2 ─ target group B ─ ECS service payments
  └─ ...

NLB ─ TLS 443 listener ─ target group TLS ─ ECS service edge-proxy
  • すべての ALB シャードは同一のルール/WAF 設定を持ちます。
  • Route 53 のヘルスチェックで異常シャードを自動的に引き抜きます。
  • ECS サービスは ECS_CONTAINER_METADATA_URI_V4 を活用し、コンテナ再起動と LB イベントを突き合わせます。

運用ガードレール

  • 負荷試験用プレイブック: 事前ウォーミング、Route 53 の重み確認、キャッシュ priming を手順化し、ピーク前に毎回実行します。
  • エラーバジェット管理: ELB の 50X やタイムアウトが月次エラーバジェットの 20% を超えた場合、リトライやグレースフルシャットダウンなどの改善タスクを優先します。
  • カオス演習: 任意のタスクをドレインさせる演習を行い、リトライとバックオフが期待通りに機能するか定期的に検証します。

学んだこと

  • ALB のスケールアウトは破壊的になり得るため、複数 ALB での分散とドレイニング調整が重要です。
  • NLB のノイジーネイバーは避けられない前提で、エクスポネンシャルバックオフとジッターを備えたクライアントが最善策です。
  • 観測性と手順化されたプレイブックが、顧客影響より先にエンジニアを動かす鍵になります。

次の繁忙期を迎える前に、自分たちの ELB スタックでも同様の検証と対策を進めておきましょう。