TT Lab
はじめる
学ぶ 学習パス コース

見知らぬシステムの前で

良いデバッグは痕跡が残らない

TT Labで続きを見る

一言でいうと

30分で正確に絞り込んで直した人と、3時間さまよって偶然直した人のコミットは、同じ形をしています。そのため、記録を残さなければ、実力も組織の資産も積み上がりません。

なぜ必要なのか

デバッグが経験年数に比例して伸びない理由は3つあります。

1つ目は、明示的に教える場がほとんどないことです。言語とフレームワークは学びますが、絞り込む手順は見よう見まねで覚えます。

2つ目は、フィードバックのかかり方が間違っていることです。症状が消えると報酬が来ます。なぜ消えたのかわからない状態も、同じように報われます。そのため、運で直した経験が実力と誤認されます。

3つ目は、よいデバッグは痕跡が残らないことです。組織がこの能力を見分けにくく、見分けられなければ育成もされません。

これに対する対応は1つだけです。痕跡を残すことです。

絞り込む手順には名前がある

記録を残すには、まず手順が必要です。経験のある人が無意識にしていることに名前を付けておけば、学べるようになります。

二分探索: リクエストが通るレイヤーを半分に切ります。クライアント → ゲートウェイ → サービス → DBなら、まずゲートウェイから直接サービスを呼んでみます。通れば前のほうが、通らなければ後ろのほうが犯人です。1回で候補が半分になります。レイヤーが8つなら、3回で1つに絞れます。

差分の絞り込み(delta debugging): うまくいくものと、いかないものの両方があるときに使います。うまくいくリクエストといかないリクエストの違いを1つずつ消していき、どの違いが消えた瞬間に症状も消えるかを探します。ヘッダー1つ、フィールド1つ、時刻1つが残ります。

時間軸を揃える: デプロイ・設定変更・トラフィック増加の時刻と、症状の開始時刻を1行に並べます。ほとんどの障害は、何かが変わった直後に始まります。「いつからか」を正確に知ることは、「何が原因か」の半分です。

仮定をひっくり返す: 30分以上絞り込めなかったなら、確実だと信じていたことの1つが間違っている可能性が高いです。「DNSは当然動く」「設定は反映された」「そのバージョンで合っている」。こういうことを、1つずつ実際に確認します。たいていここで見つかります。

記録の形式: 1枚で十分

長く書くと誰も書きません。実務で実際に続いている形式は、このくらいです。

## 증상
결제 완료 화면에서 간헐적 500 (약 20%)

## 재현
for i in $(seq 20); do curl -s -o /dev/null -w '%{http_code}
'   -X POST https://stg/api/pay -d @fixtures/pay.json; done
→ 20회 중 4~6회 500

## 배제
- 인증: 401/403 이 로그에 0건
- 네트워크: 같은 요청을 게이트웨이 안에서 직접 → 같은 비율로 실패
- 데이터: 실패한 요청의 body 가 성공한 것과 바이트 단위로 동일

## 원인
결제 서비스 파드 3개 중 1개만 옛 설정(타임아웃 1초)으로 떠 있었다.
ConfigMap 을 바꾼 뒤 rollout restart 를 하지 않아 그 파드만 옛 값을 안고 있었다.

## 수리 전후
전: 20회 중 5회 실패 / 후: 40회 중 0회 실패 (같은 명령)

## 다음에 이걸 막는 것
- [ ] ConfigMap 해시를 파드 애노테이션에 넣어 변경 시 자동 재시작 (담당: 배포팀, 3/25)

このコードブロックの韓国語の見出しは、順に、症状・再現・除外・原因・修理前後・次にこれを防ぐものという意味で、例の内容は、決済完了画面で約20%の割合で断続的に500が出ていて、決済サービスのPod3つのうち1つだけが古い設定(タイムアウト1秒)のまま動いていた、というものです。

「次にこれを防ぐもの」の項目が、この文書の価値です。原因だけが書かれた記録は、同じ障害に2回目に出会ったときに検索できる程度ですが、ここまで書かれた記録は2回目をなくします。

タイムボックスを決めておく

絞り込めないまま時間が過ぎることが、デバッグの最大のコストです。あらかじめ決めておきます。

経過 すること
15分 これまでに除外したことを文章で書きます。書いている間に、抜けているレイヤーが見えてきます
30分 確実だと信じていた仮定の1つを、実際に確認します
45分 人を呼びます。説明している途中で、自分で見つけることが半分です
60分 迂回路があるかを見ます。原因の究明とサービスの復旧は別のことです

最後の行が特に重要です。障害対応では、復旧が先で、原因はあとです。ロールバックで5分で復旧できるのに、原因を探して1時間を使うのは、間違った優先順位です。

どう動くのか

FDEが残すべき記録は4種類あります。

再現コマンド: 症状を起こす最小のコマンド1行。これがあれば、修理できたかどうかを同じ物差しで判定でき、なければ「直ったようだ」までしか言えません。

除外リスト: 確認して消したレイヤーと、その根拠。1行で十分です。auth — 401/403 이 로그에 한 건도 없음のように書きます(韓国語の文は「ログに401/403が1件もない」という意味です)。

測定値の前後: 修理前は20回中5回失敗、修理後は20回中0回。2つの数字が同じ方法で測定されたことが重要です。

去ったあとも残る文書: FDEの成功条件は特殊です。自分がいなくても回ることが成功です。常駐が終わる日にシステムも一緒に止まるなら、それはデプロイではなくレンタルだったことになります。

現場での姿

引き継ぎ文書で、顧客が最もよく開き直すのは、アーキテクチャ図ではなく障害ランブックです。よく起きる症状ごとに、最初の30分で何をするかが書かれた文書です。ランブックがないシステムは、引き渡せないシステムです。

そして文書を渡す日には、文書だけを渡さず、顧客のエンジニアがランブックどおりに障害シナリオを1つ自分で処理してみるリハーサルまで行うのが、完結です。読んで理解したことと、手が動くことは違います。

記録の形式より重要なのはタイミングです。引き継ぎ文書は最後の週ではなく、プロジェクトの中盤から積み上げる必要があります。最後の週にまとめて書いた文書は、例外なく「何ができないのか」が抜けています。そのころには本人がすでにその例外に慣れてしまい、特別だと感じないからです。

次のラボですること

4種類を実際に残します。そして最後に、採点ツールが次の人の役を務めます。書いた再現コマンドを、自分のシェルではないきれいな環境でもう一度実行します。そこで同じ数字が出てはじめて、記録が記録と呼べるようになります。