障害対応 ·

原因が分からない障害を、API・DB・インフラを横断して切り分ける手順

  • 障害対応
  • 運用
  • オブザーバビリティ

この記事で扱う問題

「一部のユーザーで API がときどき遅い」「特定の操作だけ失敗する」といった障害は、原因がアプリにあるのか、DB なのか、キャッシュなのか、ロードバランサなのか、最初は分かりません。

このとき一番まずいのは、思いついた原因を順に直してみることです。直したつもりで症状が消えても、偶然かもしれません。本当の原因が残ったまま、次の障害で同じ調査を繰り返すことになります。

判断

私は次の順で切り分けます。

  1. 影響範囲を確定する:全員か一部か。一部なら、どのエンドポイント・どのユーザー・どのクライアントのバージョンか
  2. 時系列を並べる:いつから起きているか。その前後にデプロイ、設定変更、トラフィックの変化、外部サービスの障害はなかったか
  3. 1件のリクエストを端から端まで追う:Request ID で、ロードバランサ → アプリ → DB・キャッシュ・外部 API のログをつなげる
  4. 層ごとに「正常」を確かめて除外する:ロードバランサの応答時間、アプリの処理時間、クエリの実行時間、外部 API の応答時間を比べ、どの層で時間を使っているかを特定する
  5. 仮説を立てて、再現で確かめる:「この条件なら必ず起きる」を作れてから直す
  6. 再発しない形に直す:その場の修正に加えて、同じ種類の問題が起きない設計・監視を入れる

なぜそう判断したか

障害調査で時間がかかるのは、たいてい「どこで起きているか」の特定です。層をまたぐシステムでは、症状が出る場所と原因の場所が違うことが普通です。アプリがタイムアウトしていても、原因は DB のロック待ちかもしれませんし、キャッシュの接続数の枯渇かもしれません。

だから、推測より先に事実を並べて、除外していくことを優先します。影響範囲と時系列が固まれば、候補はかなり絞れます。

この手順を回すには、日頃からの仕込みが要ります。

障害が起きてからでは、この情報は取り戻せません。

どこから設計過剰になるか

  • 小規模なサービスで、分散トレーシングの基盤まで最初から入れる必要はありません。Request ID をログに出すだけでも、調査の速さは大きく変わります
  • 明らかな原因(直前のデプロイで入ったバグなど)がすぐ分かる場合は、手順を全部踏まずに切り戻すのが先です。復旧が最優先で、原因の特定はその後です

まとめ

  • 思いついた原因を順に直すのではなく、影響範囲と時系列で候補を絞る
  • Request ID で1件のリクエストを端から端まで追い、層ごとに正常を確かめて除外する
  • 再現で確かめてから直し、再発しない設計と監視まで入れる

本記事の設計判断・事例・技術的見解は筆者によるものです。構成・文章編集には生成AIを利用しています。