Using Java Flight Recorder (JFR) in Quarkus
## **1. 서론**
[Java Flight Recorder (JFR)](https://www.oracle.com/technetwork/java/javase/8/docs/technotes/guides/jfr/index.html)는 애플리케이션을 모니터링, 프로파일링 및 문제 해결을 위해 이벤트를 캡처하는 강력한 JVM 도구입니다. Quarkus와 JFR을 통합하면 Quarkus-specific 이벤트를 추가하여 애플리케이션의 동작과 성능에 대한 자세한 통찰력을 얻을 수 있습니다.
이 기사에서는 Quarkus 프로젝트에서 JFR을 설정하고, 사용자 정의 이벤트를 생성하며, 데이터를 분석하여 잠재적인 문제를 효과적으로 진단하는 방법을 보여줍니다.
## **2. Maven 의존성**
Quarkus 프로젝트에서 Java Flight Recorder를 활성화하려면 _[quarkus-jfr](https://mvnrepository.com/artifact/io.quarkus/quarkus-jfr)_ 확장을 추가해야 합니다. 이 확장은 Quarkus와 JFR을 통합하여 모니터링 및 진단을 개선하기 위해 사용자 정의 Quarkus 이벤트를 활성화합니다:
“`xml
“`
## **3. 프로젝트 구성**
### 3.1. REST 엔드포인트 생성
간단한 REST 엔드포인트를 생성하는 것부터 시작하겠습니다. 이 리소스는 경량 애플리케이션 상호작용을 시뮬레이션합니다:
“`java
@Path(“/hello”)
public class JfrResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return “hello”;
}
}
“`
### 3.2. 비행 기록 시작
**JFR이 자동으로 기록을 시작하도록 하려면 적절한 JVM 인수를 전달해야 합니다.** Quarkus 애플리케이션에서 이를 _application.properties_ 파일이나 애플리케이션을 시작할 때의 커맨드 라인의 일부로 수행할 수 있습니다.
개발 중 다음 JVM 인수를 추가해 보겠습니다:
“`bash
quarkus dev -Djvm.args=”-XX:StartFlightRecording=name=quarkus,dumponexit=true,filename=myrecording.jfr”
“`
애플리케이션이 실행될 때 JFR을 자동으로 시작하고, 애플리케이션이 종료될 때 _myrecording.jfr_로 기록을 덤프하도록 합니다.
## **4. JFR 이벤트 저장**
기본적으로 JFR은 애플리케이션이 종료될 때 지정된 파일(_myrecording.jfr_)로 기록을 덤프합니다. 이는 터미널에서 CTRL+C를 눌러서 트리거할 수 있으며, [_jcmd_](https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html) 명령어를 사용하여 수행할 수 있습니다:
“`bash
jcmd
“`
애플리케이션의
## **5. JFR 덤프 파일 열기**
**JFR을 사용하여 애플리케이션 이벤트를 기록한 후에는 덤프 파일을 분석하여 귀중한 통찰력을 얻는 것이 중요합니다.** 두 가지 주요 도구를 사용할 수 있습니다: JFR CLI 도구는 빠른 커맨드 라인 분석을 위해 사용하고, [JDK Mission Control (JMC)](https://www.oracle.com/java/technologies/jdk-mission-control.html)는 상세한 그래픽 보기를 제공합니다.
### **5.1. JFR CLI 사용하기**
JFR CLI는 터미널에서 직접 빠르게 분석할 수 있는 경량 도구입니다. JFR 파일의 내용을 검사하려면 _jfr print_ 명령어를 사용합니다:
“`bash
jfr print myrecording.jfr
“`
명령어를 실행한 후 출력은 이벤트, 타임스탬프 및 관련 세부정보를 나열합니다:
“`
Event: io.quarkus.HttpRequest
Method: GET
Path: /hello
ResponseCode: 200
Duration: 3ms
Event: jdk.GarbageCollection
StartTime: 2024-11-10T14:23:45.123Z
Duration: 5ms
Cause: System.gc()
“`
특정 이벤트 카테고리에 집중하려면 –categories 플래그를 사용할 수 있습니다:
“`bash
jfr print –categories “quarkus” myrecording.jfr
“`
이 명령어는 출력 결과를 Quarkus 관련 이벤트만 보여주도록 필터링하여 관련 데이터를 보다 쉽게 분석할 수 있게 합니다.
### 5.2. JDK Mission Control (JMC) 사용하기
**[JMC](https://www.oracle.com/java/technologies/jdk-mission-control.html)는 깊이 있는 분석을 위한 강력한 시각화 도구를 제공하는 그래픽 인터페이스입니다.** 터미널 또는 시스템의 GUI를 사용하여 JDK Mission Control을 열 수 있습니다. JMC를 시작한 후에는 기록된 파일(myrecording.jfr)을 파일 > 파일 열기 메뉴를 통해 직접 열 수 있습니다. 로드되면 JMC는 캡처된 데이터를 직관적인 보기 및 카테고리로 정리합니다.
이벤트 브라우저에서 HTTP 요청, 메모리 사용량 및 가비지 수집과 같은 특정 이벤트를 탐색할 수 있습니다. _io.quarkus.HttpRequest_와 같은 Quarkus-specific 이벤트는 각각의 카테고리 아래에 그룹화됩니다. 타임라인 보기는 시간에 따른 이벤트를 연관 지어 성능 병목 현상 및 패턴을 식별하는 데 도움을 줍니다.
## **6. 사용자 정의 이벤트 추가하기**
**Quarkus 및 JVM이 제공하는 내장 이벤트 외에도 애플리케이션의 특정 부분을 모니터링하기 위해 사용자 정의 이벤트를 정의할 수 있습니다.** 이는 도메인 특정 동작이나 성능 지표를 추적할 때 특히 유용합니다.
사용자 정의 이벤트를 정의하려면 _jdk.jfr.Event_ 클래스를 확장하고 _@Name_으로 이벤트 이름을 지정해야 합니다:
“`java
@Name(“com.baeldung.DatabaseQueryEvent”)
public class DatabaseQueryEvent extends Event {
private final String query;
private final long executionTime;
public DatabaseQueryEvent(String query, long executionTime) {
this.query = query;
this.executionTime = executionTime;
}
public String getQuery() {
return query;
}
public long getExecutionTime() {
return executionTime;
}
}
“`
애플리케이션 코드에서 사용자 정의 이벤트를 인스턴스화하고 커밋할 수 있습니다. 예를 들어, 데이터베이스 쿼리 실행 시간을 기록하려면 다음과 같이 할 수 있습니다:
“`java
DatabaseQueryEvent event = new DatabaseQueryEvent(“SELECT * FROM users”, 15);
event.commit();
“`
이제 프로그램을 실행한 후, 생성한 사용자 정의 이벤트를 다음과 같이 확인할 수 있습니다:
“`bash
jfr print –events DatabaseQueryEvent myrecording.jfr
“`
## **7. 결론**
Java Flight Recorder와 Quarkus의 결합은 애플리케이션 성능을 모니터링하고 최적화하는 강력한 도구입니다. 내장 이벤트 및 사용자 정의 이벤트를 사용하여 애플리케이션 동작에 대한 귀중한 통찰력을 얻고, 문제를 진단하며, 효율성을 향상시킬 수 있습니다.
항상 그렇듯이 코드 조각은 [GitHub에서 확인할 수 있습니다](https://github.com/eugenp/tutorials/tree/master/quarkus-modules).