https://sundaland.tistory.com/78
[ ▶ Java Agent ]
자바 에이전트는 자바 애플리케이션의 실행 중 동작을 변경하거나 모니터링할 수 있는 특별한 프로그램이다. 자바 에이전트는 JVM (자바 가상 머신)과 상호 작용하여 클래스 로딩 시점에 바이트코드를 조작하거나, 이미 로드된 클래스의 동작을런타임에 수정할 수 있다. 이러한 기능은 성능 모니터링, 디버깅, 프로파일링, 코드 커버리지 분석, 그리고 AOP (Aspect-Oriented Programming) 구현 등 다양한 목적에 사용된다.
[ ▷ 자바 에이전트의 주요 특징 ]
1. Permain 메서드
- 자바 에이전트는 JVM이 시작될 때 premain 메서드를 통해 실행된다. 이 메서드는 JVM이 메인 애플리케이션을 실행하기 전에 호출된다.
- premain 메서드는 두 가지 형태로 아래와 같이 정의된다.
- public static void premain(String agentArgs, Instrumentation inst)
- public static void premain(String agentArgs)
2. Instrumentation API 사용
- 자바 에이전트는 Instrumentation API를 통해 클래스 로딩 과정에 개입할 수 있다. 이 API는 바이트코드를 변환하거나, 재정의할 수 있는 메서드들을 제공하며, 이를 통해 자바 에이전트는 런타임에 애플리케이션의 동작을 변경할 수 있다.
- 주요 메서드로는 클래스 로딩 시 바이트코드로 변환되는 addTransformer와 이미 로드된 클래스를 재정의 하는 redefineClasses 등이 있다.
3. 자바 에이전트 등록 및 실행
- 자바 에이전트는 JVM 시작 시 -javaagent 옵션을 통해 등록된다.
- 예를 들어, -javaagent:/path/to/agent.jar -jar myapp.jar 같은 형식이다.
- 이 옵션은 JVM이 시작될때 지정된 JAR 파일을 자바 에이전트로 인식하고, 해당 에이전트의 permain 메서드를 호출한다.
4. JAR 파일 구조
- 자바 에이전트는 JAR 파일 형태로 패키징되며, META-INF/MANIFEST.MF 파일에 Premain-Class라는 속성이 포함되어야하다. 이 속성은 JVM에 어떠 클래스의 permain 메서드를 호출할지를 지정하나.
- 예를 들어, Permain-Class: com.example.MyAgent 같은 형식이다.
[ ▷ 자바 에이전트의 일반적인 사용 사례 ]
1. 성능 모니터링
- 애플리케이션의 실행중 성능 관련 데이터를 수집하기 위해 자바 에이전트를사용하여 메서드 실행 시간, 메모리사용량 등 을 추적할 수 있다.
2. 프로파일링 도구
- 자바 에이전트는 애플리케이션의 실행을 프로파일링하는 도구로 사용되어, 실행 중인 애플리케이션의메모리 사용, 스레드 상태, CPU 사용 등을 분석할 수 있다.
3. 코드 커버리지 분석
- 자바 에이전트는 테스트 실행 중 어떤 코드가 실행되었는지를 추적하여 코드 커버리지 정보를 수집하고, 이를 바탕으로 커버리지 보고서를 생성할 수 있다.
4. AOP(Aspect-Oriented Programming)
- AspectJ와 같은 AOP 프레임워크에서 자바 에이전트를 사용하여 런타임에 클래스 파일을 변환하고, 특정 메서드 호출 전후에 코드를 삽입하는 등의 기능을 구혀할 수 있다.
5. 디버깅 및 로깅
- 자바 에이전트를 사용하여 애플리케이션의 실행 중 특정 이벤트나 상태를 실시간으로 로깅하거나, 디버깅 정보를 수집할 수 있다.
[ ▷ 자바 에이전트의 예시 코드 ]
▼ 모든 클래스가 로드될 때마다 그 클래스의 이름을 출력하는 자바 에이전트
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
public class SimpleAgent {
public static void premain(String agentArgs, Instrumentation inst) {
inst.addTransformer(new SimpleTransformer());
}
}
class SimpleTransformer implements ClassFileTransformer {
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) {
System.out.println("Transforming class: " + className);
// 바이트코드를 수정하지 않는 경우 원본 바이트코드를 반환
return classfileBuffer;
}
}
자바 에이전트는 JVM의 클래스 로딩 과정에 개입하여 애플리케이션의 동작을 실시간으로 조작할 수 있는 도구이다. 주로 Instrumentation API를 사용하여 바이트코드 수준에서의 수정 작업을 수행하며, 성능 모니터링, 프로파일링, 코드 커버리지 분석, AOP 구현 등 다양한 용도로 사용되다. 자바 에이전트는 JVM 시작 시 -javaagent 옵션을 통해 로드되며, 애플리케이션의 실행 전바에 걸쳐 중요한 역할을 할 수 있다.
[ ▷ 자바 에이전트의 종류 ]
대표적인 자바 에이전트들은 다양한 목적에 맞춰 개발된 도구들로, 주로 성능 모니터링, 프로파일링, 코드 커버리지 분석, AOP 구현 등을 위해 사용된다.
1. 자바 Flight Recorder (JFR)
- 용도: 성능 모니터링 및 프로파일링
- 설명: JFR은 JDK에 내장된 성능 모니터링 도구로, 자바 애플리케이션의 실행 중 발생하는 다양한 이벤트를 기록하고 분석하는데 사용된다. JFR은 매우 낮은 오버헤드로 성능 데이터를 수집할 수 있어, 프로덕션 환경에서 성능 문제를 분석하는데 매우 유용하다.
- 특징: JFR은 JDK에 내장되어 있으며, 별도의 설치가 필요하지 않고, -XX:StartFlightRecording 옵션으로 활성화할 수 있다.
2. JaCoCo (Java Code Coverage Library)
- 용도: 코드 커버리지 분석
- 설명: JaCoCo는 자바 애플리케이션의 테스트 커버리지를 측정하기 위한 도구이다. JaCoCo의 자바 에이전트는 테스트 실행 중 어떤 코드가 실행되었는지를 추적하여, 코드 커버리지 보고서를 생성한다.
- 특징: Maven, Gradle 등 빌드 도구와 쉽게 통합되며, CI/CD 파이프라이엔서 코드 커버리지를 자동으로 측정하고 보고할 수 있다.
3. New Relic
- 용도: 애플리케이션 성능 모니터링
- 설명: New Relic은 클라우드 기반의 애플리케이션 성능 모니터링 도구로, 자바 에이전트를 통해 애플리케이션의 성능을 모니터링하고 문제를 진단할 수 있다. New Relic의 자바 에이전트는 메서드 호출, 데이터베이스 쿼리, 외부 API 호출 등을 모니터링하여 실시간 성능 데이터를 수집한다.
- 특징: 다양한 대시보드와 실시간 성능 모니터링 기능을 제공하며, 클라우드 서비스와 통합이 용이하다.
4. AspectJ
- 용도: AOP (Aspect-Oriented Programming)
- 설명: AspectJ는 자바에서 AOP를 구현하는 프레임워크로, 자바 에이전트를 통해 런타임에 클래스 파일을 위빙 (Weaving)할 수 있다. 이를 통해 특정 포인트컷에 따라 메서드 호출 전후에 코드를 삽입하는 등의 작업을 수행할 수 있다.
- 특징: 로드 타임 위빙 (LTW)을 지원하며, 복잡한 비즈니스 로직에서 횡단 관심사를 분리하여 관리할 수 있다.
5. Byte Buddy
- 용도: 런타임 바이트코드 조작
- 설명: Byte Buddy는 자바 클래스의 바이트코드를 런타임에 동적으로 생성하거나 변환하는 라이브러리이다. 자바 에이전트를 통해 클래스 로딩 시점에서 바이트코드를 변환하는 작업을 쉽게 수행할 수 있다.
- 특징: 다양한 프레임워크와 통합이 용이하며, 바이트코드를 조작하는데 필요한 강력한 API를 제공한다.
6. BTrace
- 용도: 런타임 디버깅 및 트레이싱
- 설명: BTrace는 자바 애플리케이션의 런타임 동작을 실시간으로 추적할 수 있는 도구이다. BTrace의 자바 에이전트는 애플리케이션 코드의 변경 없이 다양한 이벤트를 실시간을 추적할 수 있다.
- 특징: 매우 가볍고, 애플리케이션의 성능에 최소한의 영향을 주며, 실시간 모니터링에 적합하다.
7. Glowroot
- 용도: 애플리케이션 성능 모니터링 (APM)
- 설명: Glowroot는 오픈 소스 APM 도구로, 자바 에이전트를 통해 애플리케이션의 성능을 모니터링한다. Glowroot는 스레드 프로파일링, 트랜잭션 추적, SQL 분석 등 다양한 기능을 제공한다.
- 특징: 설치와 설정이 간편하며, 경량화된 APM 솔루션으로 많은 개발자와 팀에서 애용된다.
자바 에이전트는 JVM에서 실행되는 자바 애플리케이션의 동작을 실시간으로 모니터링하거나 수정할 수 있는 매우 강력한 도구이다. 위에서 소개한 대표적인 자바 에이전트들은 각각 다른 목적에 맞게 설계되어 있으며, 성능 모니터링, 코드 커버리지 분석, AOP 구현, 디버깅 등 다양한 작업을 수행할 수 있다.
위의 자바 에이전트 코드는 JVM이 시작될 때 로드되며, 모든 클래스가 로드될 때마다 해당 클래스의 이름을 출력하고, 바이트코드를 수정하지 않고 원본 그래도 반환하는 간단한 자바 에이전트이다.
[ ▶ 자바 에이전트 사용 방법 ]
[ ▷ Java Agent 컴파일 및 JAR 파일 생성 ]
위의 자바 에이전트 코드를 컴파일하고, JAR 파일로 패키징해야 한다. JAR 파일에는 META-INF/MANIFEST.MF 파일에 Premain-Class 속성을 설정해야 한다.
1. SimpleAgent.java 파일로 저장
위의 코드를 SilmeAgent.java 파일로 저장한다.
2. 컴파일
javac SimpleAgent.java
3. JAR 파일 생성
JAR 파일을 생성할 때, META-INF/MANIFEST.MF 파일에 Premain-Class를 지정한다.
Premain-Class: SimpleAgent
▼ JAR 파일 생성 명령
jar cmf MANIFEST.MF simple-agent.jar SimpleAgent.class SimpleTransformer.class
[ ▷ 자바 에이전트를 사용하는 애플리케이션 실행 ]
이제 생성된 자바 에이전트 JAR 파일 (simple-agent.jar)을 애플리케이션과 함께 실행한다.
아래는 자바 에이전트를 사용하는 애플리케이션의 실행 예제이다.
1. 간단한 자바 애플리케이션 작성
public class MyApplication {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
이 코드를 MyApplication.java로 저장하고 컴파일한다.
javac MyApplication.java
2. 자바 에이전트와 함께 애플리케이션 실행
자바 에이전트를 사용하려면 -javaagent 옵션을 사용하여 JVM을 실행할 때 에이전트를 로드한다.
java -javaagent:/path/to/simple-agent.jar -cp . MyApplication
[ ▷ 실행 결과 ]
애플리케이션이 실행될 때, SimpleAgent가 로드되고, MyApplication 클래스를 포함한 모든 클래스가 로드될 때마다 클래스 이름이 출력된다.
Transforming class: MyApplication
Hello, World!
[ ▷ 요약 ]
- SimpleAgent.java 코드를 컴파일하고 JAR 파일로 패키징한다.
- -javaagent 옵션을 사용하여 자바 에이전트 JAR 파일을 로드하고 애플리케이션을 실행한다.
- 애플리케이션이 실행되는 동안 로드되는 모든 클래스 이름이 출력된다.
이 예제는 자바 에이전트의 기본적인 사용 방법을 보여주며, 실제 애플리케이션에서 다양한 목적을 위해 바이트코드 조작을 적용할 수 있다.
'스프링 AOP' 카테고리의 다른 글
Spring instrument library (0) | 2024.09.04 |
---|---|
Instrumentation API vs AspectJ (0) | 2024.09.04 |
Java Instrument API vs ASM(Abstract Syntax Manipulation) (0) | 2024.09.03 |
Java Instrumentation API (0) | 2024.09.03 |
Declaring Advice, Introductions (1) | 2024.09.02 |