🕵🏻‍♂️

Thread 상태 분석하기

Tomcat이 무엇인지, WAS를 진단할 때 어떤 부분들을 확인해야 하는지 등은 강의를 통해 확인할 수 있어요. 이 포스팅에서는 Thread dump에 대해 이야기할게요

1. Thread dump

Thread dump를 통해 Thread가 무슨 일을 하는지 알 수 있어요.

A. Thread 덤프 생성

$ ps -ef | pgrep java $ jstack [pid] > thread.dump
Shell
복사

B. Thread 덤프 내용

# 생성 시간 정보 2021-03-27 23:55:32 # JVM에 대한 정보 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.251-b08 mixed mode): # DeadLock에 대한 정보 Found one Java-level deadlock: ============================= "http-nio-8080-exec-6": waiting to lock monitor 0x00007faa62973608 (object 0x00000005c0c4b1e8, a java.lang.Object), which is held by "http-nio-8080-exec-5" "http-nio-8080-exec-5": waiting to lock monitor 0x00007faa60025508 (object 0x00000005c0c4b1f8, a java.lang.Object), which is held by "http-nio-8080-exec-6" Java stack information for the threads listed above: =================================================== "http-nio-8080-exec-6": at nextstep.subway.line.ui.LineController.findLockLeft(LineController.java:78) - waiting to lock <0x00000005c0c4b1e8> (a java.lang.Object) # Thread stack 정보 "http-nio-8080-exec-6" #47 daemon prio=5 os_prio=31 tid=0x00007faa6132c000 nid=0x7f03 waiting for monitor entry [0x0000700009bce000] java.lang.Thread.State: BLOCKED (on object monitor) at nextstep.subway.line.ui.LineController.findLockLeft(LineController.java:78) - waiting to lock <0x00000005c0c4b1e8> (a java.lang.Object) - locked <0x00000005c0c4b1f8> (a java.lang.Object)
Bash
복사
Thread 이름, 식별자, 우선순위(prio), Thread가 점유하는 메모리 주소를 의미하는 Thread ID(tid), OS에서 관리하는 Thread ID (nid), Thread 상태 (NEW | RUNNABLE | BLOCKED | WAITING | TIMED_WAITING | TERMINATED) 등의 정보를 확인할 수 있어요.

C. 실습

저장소를 clone 받습니다.
$ cd docker && docker-compose up -d
Shell
복사
a. 테스트
# 상황 1 $ curl localhost:8080/lines # 상황 2 $ curl localhost:8080/lines/lock-left $ curl localhost:8080/lines/lock-right # 상황 3 여러 브라우저 혹은 터미널로 요청해본다. $ curl localhost:8080/lines/tan $ curl localhost:8080/lines/tan ...
Shell
복사
b. Thread dump 로컬로 download
# 운영서버에서 Bastion으로 파일 옮기기 $ rsync -avzh [원격대상경로] [받을경로] # 예) $ rsync -avzh ubuntu@2.2.2.2:/home/ubuntu/log/ ./log/ # Bastion 서버에서 파일 다운로드 $ scp -i [pem키] ubuntu@1.1.1.1:/home/ubuntu/log/thread.dump .
Shell
복사

2. Arthas 활용하기

A. Arthas 설치 및 실행

VisualVM을 사용해주셔도 좋습니다.
$ curl -O https://arthas.aliyun.com/arthas-boot.jar $ java -jar arthas-boot.jar
Shell
복사

B. dashboard

쓰레드 상태, 메모리 그리고 시스템의 전반적인 상황을 확인할 수 있어요.
우선 CPU 사용량, 누적 시간이 많은 쓰레드를 확인해보세요
새로운 쓰레드를 계속 생성할 경우엔 쓰레드 풀을 사용해야 합니다

C. thread

$ thread --all $ thread -b
Shell
복사
RUNNABLE이 높을 경우 : 정상적인 상태이나, CPU 사용량이 비정상적으로 높을 경우 확인해봐야 합니다.
BLOCKED가 높을 경우 : Lock 상태의 쓰레드이므로 원인을 파악해봅니다.
WAITING / TIMED_WAITING : 문제되지 않아요.

D. trace