반응형
Arthas 란
- 알리바바 미들웨어팀이 오픈소스로 공개한 자바 진찰도구
요구사항
- JDK 6 이상
- Linix, Mac, Windows
설치
실행
- java -jar arthas-boot.jar
- 감지된 jvm을 선택한다
Arthas With Spring boot with docker
- 도커 컨테이너에서 실행되는 어플리케이션(JVM)에 접근하기 위해서는 컨테이너 내부에 arthas를 설치해야한다...
- jre만으로는 arthas가 정상작동 안하며 jdk를 설치해야한다..
단지서버에서 가용되는 openjdk:11-jre-slim-buster (JRE) 일시 arthas 실행시
정상적으로 동작하지 못한다.
Spring boot + Docker + jdk11
- Dockerfile
FROM openjdk:11
ARG JAR_FILE=build/libs/simpleserver-0.0.1-SNAPSHOT.jar
COPY ${JAR_FILE} app.jar
COPY --from=hengyunabc/arthas:latest /opt/arthas /opt/arthas
ENTRYPOINT ["java","-jar","/app.jar"]
도커 이미지 빌드 및 실행 시 컨테이너 내부에 지정된 경로로 arthas가 설치(복사)되어 있다.
도커 내부의 arthas를 실행시켜서 어플리케이션에 접근
sudo docker exec -it 0a058e068b8b /bin/bash -c "java -jar /opt/arthas/arthas-boot.jar"
Arthas 기능
Dashboard
$ dashboard
Thread 정보 확인
thread ${쓰레드번호}
실시간 쓰레드 동작 상태 확인
@Service
public class DelayService {
public void delay(final long delayMilSec) throws InterruptedException {
Thread.sleep(delayMilSec);
}
}
[arthas@1]$ thread 42
"http-nio-80-exec-7" Id=42 TIMED_WAITING
at java.base@11.0.12/java.lang.Thread.sleep(Native Method)
at com.example.simpleserver.service.DelayService.delay(DelayService.java:8)
at com.example.simpleserver.controller.CheckController.delayCheck(CheckController.java:26)
at java.base@11.0.12/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base@11.0.12/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base@11.0.12/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base@11.0.12/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1726)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base@11.0.12/java.lang.Thread.run(Thread.java:829)
Watch (실시간 감시)
watch ${페키지 포함한 클래스} ${메서드명}
1초의 딜레이를 주는 메서드에서 1001.621864ms 가 걸리는것을 확인 가능
EX
public Integer add(final int a, final int b) {
return a+b;
}
단순히 2수를 더하는 메서드에서 return값을 실시간으로 확인 가능하다.
AtEndter, AtExit의 depth를 2까지 주어서 메서드 호출시, 리턴시의 파라이터 및 리턴값 확인
Logger
Logger
logger -c ${classLoder 인스턴스ID} --name ${logger name} --level ${변경할 debug level}
Heapdump
heapdump ${떨굴 경로}
heapdum --live ${떨굴 경로}
SC
SM
Reference
- https://github.com/alibaba/arthas
- https://arthas.aliyun.com/doc/en/index.html
- https://cdmana.com/2021/06/20210610090208101P.html
반응형
'개발 일지' 카테고리의 다른 글
MSA Transaction 전략 (LLTs) - SAGA 패턴 (0) | 2023.04.16 |
---|---|
Kafka 압축 방식 성능 평가 (0) | 2023.04.13 |
자동화 공격이란 (0) | 2022.11.25 |
DID 란 (0) | 2022.11.25 |
Spring TransactionEventListener (0) | 2022.11.23 |