LabHub
배우기 러닝패스 코스

Tomcat & nginxの運用

ログで障害の原因を絞る

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

운영 로그(catalina.out, GC 로그, 액세스 로그, nginx 에러 로그)에서 근거를 뽑아 장애 원인을 좁히고, 숫자가 들어간 장애 보고서를 작성할 수 있게 됩니다.

왜 중요한가

장애 대응에서 가장 흔한 실패는 502 에 타임아웃을 늘리는 것입니다. 502 는 "유효하지 않은 응답을 받았다"이고 504 가 "시간 안에 응답하지 않았다"입니다. 둘을 섞으면 몇 시간을 낭비합니다. 또 OOM 은 종류(Java heap space / Metaspace / unable to create native thread)에 따라 조치가 완전히 달라서, 메시지를 안 읽고 -Xmx 만 올리면 오히려 나빠질 수 있습니다. 로그에서 숫자를 뽑는 손이 있으면 이 판단이 추측에서 근거로 바뀝니다.

단계

  1. /root/ts 를 만들고 /opt/lab/fixtures/tomcat/logs/ 의 네 파일을 그대로 복사합니다. (catalina-oom.log, gc.log, access.log, nginx-error.log) 내용이 원본과 동일해야 합니다.
  2. catalina-oom.log 에서 OutOfMemoryError 를 찾아 /root/ts/oom.txt 를 만듭니다. 두 줄이고 형식은 정확히 아래와 같습니다.
    time=<로그에 적힌 타임스탬프>
    type=<OOM 종류 문자열>
    
    typeJava heap space / Metaspace / GC overhead limit exceeded / unable to create native thread 중 하나입니다.
  3. gc.log 를 분석해 /root/ts/gc.txt 를 만듭니다. 두 줄입니다.
    fullgc=<Full GC 발생 횟수>
    maxpause=<가장 긴 정지 시간, 밀리초, 소수점 포함 그대로>
    
  4. access.log 에서 처리 시간이 긴 URL 상위 5개를 뽑아 /root/ts/slow.csv 를 만듭니다. 첫 줄은 url,count,max_ms, max_ms 내림차순 정렬입니다.
  5. access.log 에서 5xx 응답을 URL 별로 집계해 /root/ts/5xx.csv 를 만듭니다. 첫 줄은 url,status,count, 건수 내림차순 정렬입니다.
  6. nginx-error.log 에서 업스트림 오류를 원인별로 집계해 /root/ts/upstream.csv 를 만듭니다. 첫 줄은 code,cause,count. code502 또는 504, causeconnection refused 또는 timeout 입니다.
  7. Tomcat 을 기동하고 스레드 덤프를 떠서 /root/ts/threads.txt 에 저장한 뒤, /root/ts/threadstat.txt 를 만듭니다. 두 줄입니다.
    total=<덤프에 있는 전체 스레드 수>
    waiting=<WAITING 상태 스레드 수>
    
    두 값은 threads.txt 의 내용과 일치해야 합니다.
  8. /root/ts/rca.md 를 작성합니다. ## 현상, ## 원인, ## 조치, ## 재발방지 네 개의 h2 제목이 있어야 하고, 2단계의 OOM 종류 문자열과 3단계의 fullgc 숫자가 본문에 그대로 인용돼야 합니다.

참고

로그 사본 확보

/root/ts 를 만들고 /opt/lab/fixtures/tomcat/logs/ 의 네 파일을 그대로 복사합니다. (catalina-oom.log, gc.log, access.log, nginx-error.log) 내용이 원본과 동일해야 합니다.

장애 분석의 첫 행동은 원본 보존입니다. 분석 중에 로그가 로테이션되거나 덮어써지는 일이 실제로 일어납니다.

OOM 발생 시각과 종류 확인

catalina-oom.log 에서 OutOfMemoryError 를 찾아 /root/ts/oom.txt 를 만듭니다. 두 줄이고 형식은 정확히 아래와 같습니다.

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

typeJava heap space / Metaspace / GC overhead limit exceeded / unable to create native thread 중 하나입니다.

OutOfMemoryError 는 종류에 따라 조치가 완전히 다릅니다. 메시지 뒷부분에 종류가 적혀 있습니다.

GC 로그 분석

gc.log 를 분석해 /root/ts/gc.txt 를 만듭니다. 두 줄입니다.

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

Full GC 만 세어야 합니다. 정지 시간은 각 줄 끝의 밀리초 값입니다. 소수점이 있으니 정렬 방식에 주의하세요.

느린 URL 상위 추출

access.log 에서 처리 시간이 긴 URL 상위 5개를 뽑아 /root/ts/slow.csv 를 만듭니다. 첫 줄은 url,count,max_ms, max_ms 내림차순 정렬입니다.

액세스 로그의 마지막 필드가 처리 시간입니다. URL 별로 묶어 최대값을 구해야 합니다. awk 의 연관 배열을 쓰면 한 번의 스캔으로 끝납니다.

5xx 발생 분포

access.log 에서 5xx 응답을 URL 별로 집계해 /root/ts/5xx.csv 를 만듭니다. 첫 줄은 url,status,count, 건수 내림차순 정렬입니다.

상태코드 필드를 정확히 지목해야 합니다. 5로 시작하는 세 자리만 골라 URL 별로 집계하세요.

502 와 504 원인 구분

nginx-error.log 에서 업스트림 오류를 원인별로 집계해 /root/ts/upstream.csv 를 만듭니다. 첫 줄은 code,cause,count. code502 또는 504, causeconnection refused 또는 timeout 입니다.

nginx 에러 로그의 문구가 원인을 말해 줍니다. 연결 자체가 거부된 것과 시간이 초과된 것은 다른 문구로 남습니다.

실제 스레드 덤프 분석

Tomcat 을 기동하고 스레드 덤프를 떠서 /root/ts/threads.txt 에 저장한 뒤, /root/ts/threadstat.txt 를 만듭니다. 두 줄입니다.

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

두 값은 threads.txt 의 내용과 일치해야 합니다.

실행 중인 톰캣에서 덤프를 뜬 뒤, 상태별로 스레드 수를 셉니다. 덤프에서 스레드 상태는 대문자 키워드로 나타납니다.

장애 보고서 작성

/root/ts/rca.md 를 작성합니다. ## 현상, ## 원인, ## 조치, ## 재발방지 네 개의 h2 제목이 있어야 하고, 2단계의 OOM 종류 문자열과 3단계의 fullgc 숫자가 본문에 그대로 인용돼야 합니다.

보고서의 가치는 숫자에 있습니다. 앞 단계에서 뽑은 값을 그대로 인용하세요. 재발 방지 항목에는 '주의한다' 대신 구체적인 설정이나 감시 항목을 적습니다.