이번에 JVM 밑바닥까지 파헤치기를 보면서, 지금 AWS EC2에서 운영중인 서비스를 모니터링 하고싶다는 생각이 들었다.
하지만 현재 서비스는 Alpine Linux 기반의 JRE 이미지를 베이스로 운영되고 있어, jps나 jstat 같은 기본적인 JDK 모니터링 툴조차 포함되어 있지 않은 상태였다. 또한 JConsole이나 VisualVM의 Remote기능을 활용하기에는 EC2에 전용 Port를 열어야 하고, 기타 설정도 만지는 등 시간이 좀 걸릴 것 같았다.
따라서, Alibaba에서 만든 Arthas라는 오픈소스를 이용해 보기로 했다.
Arthas Git Repository
설치과정부터 알아보자.
먼저, 자바 프로그램을 돌리고 있는 컨테이너 안으로 접속하자.
여기서 Quick Start에 나와있는 방법대로
curl -O https://arthas.aliyun.com/arthas-boot.jar
명령어를 입력한다. 필자는 runtime Base Image로 eclipse-temurin:21-jre-alpine를 이용하고 있어서 wget으로 진행하였다.
그럼 다음과 같이 arthas-boot.jar 파일이 받아진다.

이제 다음 명령어를 입력하면, 에러가 발생한다. 자바 프로세스를 못 찾고 있으므로, pid를 설정하라는 문구이다. 혹시 에러가 발생하지 않으면,
java -jar arthas-boot.jar

aux 명령어를 사용해 현재 프로세스를 확인하자.

1번 프로세스에서 자바를 실행하고 있으므로, pid를 선택해준다.

그런데 또, 연결 실패 예외가 발생한다.
에러 내용을 살펴보면, com/sun/tools/attach/AgentLoadException 이런 Class를 찾지 못했다고 하는데, 이는 Arthas가 JDK에 있는 Attach API를 통해 동작하기 때문이다.
하지만 현재 JRE를 이용하고 있기 때문에, 다른 방법으로 설치하여야 한다.
먼저 다시 우분투 환경으로 돌아간다. 이곳에 JDK를 설치 후, Arthas를 설치하고, 컨테이너 내부 프로세스에 Agent를 Attach API로 주입해 줄 것이다.
sudo apt update
sudo apt install -y openjdk-21-jdk-headless

curl -O https://arthas.aliyun.com/arthas-boot.jar

CONTAINER_PID=$(sudo docker inspect -f '{{.State.Pid}}' jamjam-backend)
sudo java -jar arthas-boot.jar --target-ip 0.0.0.0 $CONTAINER_PID

이렇게 로그에서 연결은 실패했지만, Attach 작업은 성공하였다. 이는 도커 컨테이너에서 네트워크를 격리하고 있기 때문이다.
이제 다시 컨테이너 안으로 들어가자. 여기서 아까 실패했던 명령어를 다시 입력해주면,
java -jar arthas-boot.jar 1

성공적으로 접속이 된 모습을 볼 수 있다.
이제 간단한 기능들을 알아보자.
먼저, 대시보드를 보자.
dashboard

이렇게 현재 실행중인 스레드 정보, 메모리 정보, 런타임 정보를 볼 수 있다. 이는 기본값인 5초 주기로 계속 pooling되며, 옵션으로 조정이 가능하다.
또한, 각 메소드를 실행하는데 걸리는 시간 또한 알 수 있다.
trace <패키지경로.클래스명> <메서드명>

다음과 같이, 각 메소드마다 걸리는 시간이 출력된다.
이를 통해 어느 메소드에서 시간이 많이 소모되는지도 알 수 있다. 와일드카드 사용도 가능하니 참고하자.