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

Tomcat & nginxの運用

ログで障害の原因を絞る

TT Labで続きを見る

目標

運用ログ(catalina.out、GCログ、アクセスログ、nginxエラーログ)から根拠を抜き出して障害の原因を絞り込み、数字の入った障害報告書を作成できるようになります。

なぜ重要なのか

障害対応で最もよくある失敗は、502でタイムアウトを延ばすことです。502は「無効なレスポンスを受け取った」で、504は「時間内に応答がなかった」です。2つを混同すると、何時間も無駄にします。また、OOMは種類(Java heap space / Metaspace / unable to create native thread)によって、対応が完全に違うので、メッセージを読まずに-Xmxだけを上げると、かえって悪化することがあります。ログから数字を取り出す手があれば、この判断が推測から根拠に変わります。

ステップ

  1. /root/tsを作成して、/opt/lab/fixtures/tomcat/logs/の4つのファイルをそのままコピーします。(catalina-oom.log、gc.log、access.log、nginx-error.log)内容が原本と同一である必要があります。
  2. catalina-oom.logからOutOfMemoryErrorを探して、/root/ts/oom.txtを作成します。2行で、形式は次のとおりです(プレースホルダーは、順にログに書かれたタイムスタンプと、OOMの種類の文字列です)。
    time=<로그에 적힌 타임스탬프>
    type=<OOM 종류 문자열>
    
    typeは、Java heap space / Metaspace / GC overhead limit exceeded / unable to create native threadのいずれかです。
  3. gc.logを分析して、/root/ts/gc.txtを作成します。2行です(プレースホルダーは、順にFull GCの発生回数と、最も長い停止時間です。停止時間はミリ秒で、小数点を含めてそのまま書きます)。
    fullgc=<Full GC 발생 횟수>
    maxpause=<가장 긴 정지 시간, 밀리초, 소수점 포함 그대로>
    
  4. access.logから、処理時間が長いURLの上位5個を抜き出して、/root/ts/slow.csvを作成します。1行目はurl,count,max_msで、max_msの降順に並べます。
  5. access.logから5xxのレスポンスをURLごとに集計して、/root/ts/5xx.csvを作成します。1行目はurl,status,countで、件数の降順に並べます。
  6. nginx-error.logからアップストリームのエラーを原因別に集計して、/root/ts/upstream.csvを作成します。1行目はcode,cause,countです。codeは502または504、causeはconnection refusedまたはtimeoutです。
  7. Tomcatを起動して、スレッドダンプを取って/root/ts/threads.txtに保存したあと、/root/ts/threadstat.txtを作成します。2行です(プレースホルダーは、順にダンプにある全スレッド数と、WAITING状態のスレッド数です)。
    total=<덤프에 있는 전체 스레드 수>
    waiting=<WAITING 상태 스레드 수>
    
    2つの値は、threads.txtの内容と一致する必要があります。
  8. /root/ts/rca.mdを作成します。## 현상、## 원인、## 조치、## 재발방지という4つのh2見出し(韓国語の見出しは、順に「現象」「原因」「対処」「再発防止」を意味します)が必要で、ステップ2のOOMの種類の文字列と、ステップ3のfullgcの数字が、本文にそのまま引用されている必要があります。

参考

ログのコピーの確保

/root/tsを作成して、/opt/lab/fixtures/tomcat/logs/の4つのファイルをそのままコピーします。(catalina-oom.log、gc.log、access.log、nginx-error.log)内容が原本と同一である必要があります。

障害分析の最初の行動は、原本の保全です。分析中にログがローテーションされたり上書きされたりすることが、実際に起きます。

OOMの発生時刻と種類の確認

catalina-oom.logからOutOfMemoryErrorを探して、/root/ts/oom.txtを作成します。2行で、形式は次のとおりです(プレースホルダーは、順にログに書かれたタイムスタンプと、OOMの種類の文字列です)。

time=<로그에 적힌 타임스탬프>
type=<OOM 종류 문자열>

typeは、Java heap space / Metaspace / GC overhead limit exceeded / unable to create native threadのいずれかです。

OutOfMemoryErrorは、種類によって対応が完全に異なります。メッセージの後ろの部分に、種類が書かれています。

GCログの分析

gc.logを分析して、/root/ts/gc.txtを作成します。2行です(プレースホルダーは、順にFull GCの発生回数と、最も長い停止時間です。停止時間はミリ秒で、小数点を含めてそのまま書きます)。

fullgc=<Full GC 발생 횟수>
maxpause=<가장 긴 정지 시간, 밀리초, 소수점 포함 그대로>

Full GCだけを数える必要があります。停止時間は、各行の末尾のミリ秒の値です。小数点があるので、並べ替えの方式に注意してください。

遅いURLの上位の抽出

access.logから、処理時間が長いURLの上位5個を抜き出して、/root/ts/slow.csvを作成します。1行目はurl,count,max_msで、max_msの降順に並べます。

アクセスログの最後のフィールドが処理時間です。URLごとにまとめて、最大値を求める必要があります。awkの連想配列を使えば、1回のスキャンで終わります。

5xxの発生分布

access.logから5xxのレスポンスをURLごとに集計して、/root/ts/5xx.csvを作成します。1行目はurl,status,countで、件数の降順に並べます。

ステータスコードのフィールドを正確に指定する必要があります。5で始まる3桁だけを選んで、URLごとに集計してください。

502と504の原因の区別

nginx-error.logからアップストリームのエラーを原因別に集計して、/root/ts/upstream.csvを作成します。1行目はcode,cause,countです。codeは502または504、causeはconnection refusedまたはtimeoutです。

nginxのエラーログの文言が、原因を教えてくれます。接続そのものが拒否されたことと、時間が超過したことは、別の文言で残ります。

実際のスレッドダンプの分析

Tomcatを起動して、スレッドダンプを取って/root/ts/threads.txtに保存したあと、/root/ts/threadstat.txtを作成します。2行です(プレースホルダーは、順にダンプにある全スレッド数と、WAITING状態のスレッド数です)。

total=<덤프에 있는 전체 스레드 수>
waiting=<WAITING 상태 스레드 수>

2つの値は、threads.txtの内容と一致する必要があります。

実行中のTomcatからダンプを取ったあと、状態別にスレッド数を数えます。ダンプでスレッドの状態は、大文字のキーワードとして現れます。

障害報告書の作成

/root/ts/rca.mdを作成します。## 현상、## 원인、## 조치、## 재발방지という4つのh2見出し(韓国語の見出しは、順に「現象」「原因」「対処」「再発防止」を意味します)が必要で、ステップ2のOOMの種類の文字列と、ステップ3のfullgcの数字が、本文にそのまま引用されている必要があります。

報告書の価値は数字にあります。前のステップで抜き出した値を、そのまま引用してください。再発防止の項目には、「注意する」の代わりに、具体的な設定や監視項目を書きます。