JMX(Java Management Extensions)
JMX(Java Management eXtensions)는 응용 프로그램(소프트웨어)/객체/장치 (프린터 등) 및 서비스 지향 네트워크 등을 감시 관리를 위한 도구를 제공하는 자바 API이다.
JDK 1.5 이상부터 기본적으로 탑재된 기능 자바 어플리케이션의 모니터링과 관리 기능을 제공한다. Non-Java Resource와 하드웨어에 대해 wrapping한 인터페이스를 제공하며, API를 외부로 노출해 application 설정 및 통계데이터를 수집할 수 있는 기능을 제공한다.
mBean으로 알려진 하나 이상의 사용자 JavaBean 오브젝트를 통해(혹은 리소스를 호출하는) 애플리케이션, 디바이스, 서비스를 원격으로 제어할 수 있다.
mBean들은 mBean 서버에 등록되며, mBean 서버는 리소스에 접근하는 모든 원격 매니저를 관리한다.
- MBean(Managed Bean) 플랫폼 혹은 사용자에 의해 만들어진 모니터링용 객체.
- Standard MBean, Dynamic MBean, Model MBean, Open MBean 4가지 종류로 나뉨
- MBean Server : MBean을 등록. MBeans를 모니터링하기 원하는 원격 JMX 관리자는 MBean Server를 통하여 정보를 획득
- agent service : MBeans를 관리하는 (개발자가 제작한) 서비스 - client
MXBean( Managed Extended Bean )은 Java Management Extensions (JMX)의 일부로, JMX 프로토콜을 사용합니다. JMX 프로토콜은 Java 애플리케이션에서 모니터링 및 관리를 위한 표준화된 방법을 제공합니다.
RMI(Remote Method Invocation)는 기본적으로 TCP/IP 프로토콜을 사용하여 통신합니다. RMI는 자바에서 분산 객체 호출을 처리하는 메커니즘으로, 원격 서버에서 객체의 메서드를 로컬 객체처럼 호출할 수 있도록 해줍니다.
RMI의 통신 방식은 다음과 같습니다
1. 객체 전송: RMI는 원격 객체의 메서드를 호출하기 위해 네트워크를 통해 객체와 데이터를 전송합니다. 이 과정에서 기본적으로 TCP/IP를 사용하여 데이터가 송수신됩니다.
2. RMI 레지스트리: RMI는 "RMI 레지스트리"라는 서비스를 통해 원격 객체를 찾습니다. 클라이언트가 원격 객체를 호출하려면 먼저 RMI 레지스트리에서 객체를 조회한 후, TCP/IP 프로토콜을 통해 원격 객체와의 연결을 설정합니다.
3.RMI 통신: 원격 객체의 메서드를 호출할 때, 호출은 TCP/IP 네트워크를 통해 전달됩니다. Java RMI는 내부적으로 TCP/IP 기반의 소켓을 이용해 객체와 메서드 호출 정보를 전송하고, 그 결과를 클라이언트로 되돌려 보냅니다.
JMX 프로토콜은 RMI (Remote Method Invocation) 프로토콜을 기반으로 하며, 원격으로 JMX MBean을 연결하고 접근할 수 있도록 합니다. RMI는 자바 애플리케이션 간에 객체를 직접 주고받을 수 있도록 해주는 기술입니다.
따라서, MXBean은 RMI 프로토콜을 사용하여 JMX 서버와 클라이언트 사이의 통신을 처리하며, 자바 애플리케이션 간에 객체를 주고받을 수 있도록 합니다.
public interface MyMXBean {
public void setMessage(String msg);
public String getMessage();
}
public class MyMXBeanImpl implements MyMXBean {
private String message;
@Override
public void setMessage(String msg) {
message = msg;
}
@Override
public String getMessage() {
return message;
}
}
public class MyMXBeanServer {
public static void main(String[] args) throws Exception {
// MBeanServer 생성
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
// JMX 커넥터 생성
String host = "127.0.0.1"; // 서버 IP 주소
int port = 9999; // 서버 포트 번호
// Rmi registry에 서버 IP, port를 설정한다.
Registry registry = LocateRegistry.createRegistry(port);
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/server");
JMXConnectorServer connector = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
// 커넥터 시작
connector.start();
// MBean 등록
ObjectName mxbeanName = new ObjectName("jmx:type=MyMXBean");
MyMXBean mxbean = new MyMXBeanImpl();
mbs.registerMBean(mxbean, mxbeanName);
// 클라이언트 요청 대기
System.out.println("MXBean Server started, waiting for client requests...");
Thread.sleep(Long.MAX_VALUE);
}
}
public class MyMXBeanClient {
public static void main(String[] args) throws Exception {
// JMX 커넥터 생성
String host = "localhost"; // 서버 IP 주소
int port = 9999; // 서버 포트 번호
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/server");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
// MBean 조회
ObjectName mxbeanName = new ObjectName("jmx:type=MyMXBean");
MyMXBean mxbean = JMX.newMXBeanProxy(mbsc, mxbeanName, MyMXBean.class);
// MXBean 메서드 호출
mxbean.setMessage("Hello, MXBean!");
System.out.println(mxbean.getMessage());
// 커넥터 종료
jmxc.close();
}
}
Jolokia
Jolokia는 REST API를 통해 JMX를 사용할 수 있도록 하는 라이브러리입니다. 따라서 Jolokia를 사용하면 원격으로 JMX 데이터를 검색하고 조작할 수 있습니다.
Jolokia는 JMX MBean을 HTTP 요청으로 노출하므로, 서버에 웹 애플리케이션이 설치되어 있어야 합니다.
JMX (Java Management Extensions)는 자바 애플리케이션의 모니터링 및 관리를 위한 표준 API이지만, JMX를 사용하는 것은 불편한 경우가 있습니다. JMX는 RMI (Remote Method Invocation)를 사용하여 원격 애플리케이션을 모니터링할 수 있지만, 보안 문제 및 네트워크 설정 등 다양한 이슈가 있을 수 있습니다.
Jolokia는 JMX 데이터를 HTTP REST API를 통해 노출하므로, 원격으로 JMX 데이터를 검색하고 조작할 수 있습니다. 이를 통해 네트워크 설정 및 보안 문제를 해결할 수 있으며, 더 간단한 방식으로 애플리케이션을 모니터링하고 관리할 수 있습니다.
또한, Jolokia는 다양한 프로토콜을 지원하므로, JMX 데이터를 다른 언어로 구현된 클라이언트에서도 사용할 수 있습니다. 이를 통해 다양한 플랫폼에서 동작하는 애플리케이션을 모니터링하고 관리할 수 있습니다.
따라서, Jolokia는 JMX의 보완적인 역할을 하며, 보안 문제 및 네트워크 설정 등을 해결할 수 있는 간편한 방식으로 애플리케이션을 모니터링하고 관리할 수 있도록 합니다.
public class MyMXBeanClient {
public static void main(String[] args) throws Exception {
// Jolokia Client 생성
String host = "localhost"; // 서버 IP 주소
int port = 8080; // 서버 포트 번호
System.out.println(new URL("http", host, port, "").toString());
J4pClient j4pClient = new J4pClient(new URL("http", host, port, "").toString());
// MXBean 데이터 조회
J4pReadRequest request = new J4pReadRequest("com.app.woo.jmx:type=MyMXBean", "Message");
J4pReadResponse response = j4pClient.execute(request);
// JSON 데이터 파싱
Object value = response.getValue();
if (value instanceof JSONObject) {
JSONObject jsonObject = (JSONObject)value;
String message = (String)jsonObject.get("Message");
System.out.println("Message: " + message);
}
}
}
dependencies {
implementation 'org.jolokia:jolokia-core:1.7.1'
implementation 'org.jolokia:jolokia-jvm:1.7.1'
}
Actuator
Spring Actuator는 Spring Boot 애플리케이션의 상태와 동작을 모니터링하거나 관리할 수 있는 다양한 기능을 제공하는 서브 프로젝트입니다. 이를 통해 애플리케이션의 상태를 점검하고, 메트릭(metrics), 애플리케이션 설정, 사용 중인 스레드 정보 등을 노출하거나 조작할 수 있습니다.
주요 기능
- 모니터링 및 진단
- 애플리케이션의 상태(health)를 확인하고, 의존성, 데이터베이스, 메시징 시스템 등의 연결 상태를 검사합니다.
- 메모리 사용량, 활성 스레드 수, CPU 사용량 등 다양한 메트릭을 제공합니다.
- 엔드포인트 노출
- HTTP로 접근 가능한 RESTful 엔드포인트를 통해 애플리케이션의 상태 정보를 제공합니다.
- 기본적으로 /actuator 경로를 통해 엔드포인트를 접근합니다.
- 예: /actuator/health, /actuator/metrics
- 확장성
- 커스텀 엔드포인트를 정의하거나, 기본 엔드포인트를 확장할 수 있습니다.
- 추가적인 모니터링이나 제어 로직을 쉽게 통합할 수 있습니다.
- 서드파티 통합
- Prometheus, Grafana, ELK(Stack), Zipkin, Micrometer 등과 같은 모니터링/분석 도구와 손쉽게 연동할 수 있습니다.
주요 Actuator 엔드포인트
그 외 endpoint
https://docs.spring.io/spring-boot/reference/actuator/endpoints.html
Endpoints :: Spring Boot
If you add a @Bean annotated with @Endpoint, any methods annotated with @ReadOperation, @WriteOperation, or @DeleteOperation are automatically exposed over JMX and, in a web application, over HTTP as well. Endpoints can be exposed over HTTP by using Jersey
docs.spring.io
build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
// Spring Boot Actuator (JMX 지원 포함)
implementation 'org.springframework.boot:spring-boot-starter-actuator'
// https://mvnrepository.com/artifact/org.jolokia/jolokia-core
implementation group: 'org.jolokia', name: 'jolokia-core', version: '1.7.2'
implementation group: 'org.jolokia', name: 'jolokia-support-spring', version: '2.1.2'
}
application.properties
spring.jmx.enabled=true
# Actuator의 Jolokia 엔드포인트 활성화
management.endpoints.web.exposure.include=health,info,jolokia
management.endpoint.health.show-details=always
management.endpoint.jolokia.enabled=true
JVMMonitoringService.java
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.ThreadMXBean;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.stereotype.Component;
@Component
@ManagedResource(objectName = "com.example.mxbean.jolokia:type=JVMMonitoringService", description = "Custom MBean for Monitoring")
public class JVMMonitoringService implements JVMMonitoringServiceMBean {
private final OperatingSystemMXBean osMXBean;
private final MemoryMXBean memoryMXBean;
private final ThreadMXBean threadMXBean;
public JVMMonitoringService() {
this.osMXBean = ManagementFactory.getOperatingSystemMXBean();
this.memoryMXBean = ManagementFactory.getMemoryMXBean();
this.threadMXBean = ManagementFactory.getThreadMXBean();
}
// 속성으로 정의
@ManagedAttribute(description = "System Load Average")
@Override
public double getSystemLoadAverage() {
return osMXBean.getSystemLoadAverage();
}
// 속성으로 정의
@ManagedAttribute(description = "Heap Memory Usage")
@Override
public long getHeapMemoryUsage() {
return memoryMXBean.getHeapMemoryUsage().getUsed();
}
// 속성으로 정의
@ManagedAttribute(description = "Thread Count")
@Override
public int getThreadCount() {
return threadMXBean.getThreadCount();
}
}
JVMMonitoringServiceMBean.java
public interface JVMMonitoringServiceMBean {
double getSystemLoadAverage();
long getHeapMemoryUsage();
int getThreadCount();
}
GET request
http://localhost:8080/actuator/jolokia/read/cohttp://m.example.mxbean.jolokia:type=JVMMonitoringService/HeapMemoryUsage
response
https://ko.wikipedia.org/wiki/JMX
'WEB개발 > JAVA' 카테고리의 다른 글
메서드 참조, function, consumer, supplier (0) | 2024.12.18 |
---|---|
[JAVA] 메모리 스택, 힙 (0) | 2022.10.31 |
[JAVA] Thread-Safe, Concurrent Collection class, Double Checked Locking (0) | 2021.09.23 |
[JAVA] 객체 직렬화 serialization, IOStream (0) | 2021.08.25 |
[JAVA] AtomicInteger (thread-safe) (0) | 2021.08.13 |