JMX는 자바 애플리케이션을 모니터링하고 관리하는 표준 방법
- MBeans : 컴포넌트를 노출해 외부의 JMX 클라이언트가 오퍼레이션 호출, 속성 검사, MBeans의 이벤트 모니터링을 통해 애플리케이션을 관리
이번 장에서는 액추에이터 엔드포인트가 어떻게 MBeans로 노출되는지 살펴보면서 스프링과 JMX를 알아본다.
16장의 표 16.1을 보면 /heapdump를 제외한 모든 액추에이터 엔드포인트가 MBeans로 노출되어 있음.
- 어떤 JMX 클라이언트(예. JConsole)를 사용해도 현재 실행 중인 스프링 부트 애플리케이션의 앷에이터 엔드포인트 MBeans와 연결 가능.
JConsole을 사용하면 그림 18.1과 같이 org.springframewor.boot 도메인 아래에 나타난 액추에이터 엔드포인트 MBeans들을 볼 수 있음.
- JConsole : JDK에 포함되어 있으며, JDK가 설치된 후 홈 디렉토리의 /bin 서브 디렉터리에 있는 jconsole을 실행하면 된다.
management:
endpoints:
jmx:
exposure:
include: health, info, bean, conditions
exclude는 include와 반대로 적으면 됨.
JConsole에서 액추에이터 MBeans 중 하나의 관리용 오퍼레이션을 호출할 때
- 왼쪽 패널 트리의 해당 엔드포인트 MBeans를 확장한 후 Operations 아래의 원하는 오페레이션을 선택하면 됨.
package tacos.tacos;
import java.util.concurrent.atomic.AtomicLong;
import javax.management.Notification;
import org.springframework.data.rest.core.event.AbstractRepositoryEventListener;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.jmx.export.notification.NotificationPublisher;
import org.springframework.jmx.export.notification.NotificationPublisherAware;
import org.springframework.stereotype.Service;
@Service
@ManagedResource
public class TacoCounter
extends AbstractRepositoryEventListener<Taco>
implements NotificationPublisherAware {
private AtomicLong counter;
private NotificationPublisher np;
public TacoCounter(TacoRepository tacoRepo) {
long initialCount = tacoRepo.count();
this.counter = new AtomicLong(initialCount);
}
@Override
public void setNotificationPublisher(NotificationPublisher np) {
this.np = np;
}
@Override
protected void onAfterCreate(Taco entity) {
counter.incrementAndGet();
}
@ManagedAttribute
public long getTacoCount() {
return counter.get();
}
@ManagedOperation
public long increment(long delta) {
return counter.addAndGet(delta);
}
}
Abstract Repository EventListener의 서브클래스이므로 Taco 객체가 TacoRepositroy를 통해 저장될 때 퍼시스턴스 관련 이벤트를 받을 수 있음 -> 새로운 Taco 객체가 생성되어 리퍼지터리에 저장될 때마다 onAftewrCreate() 메서드가 호출되어 카운터를 1씩 증가시킴.
MBeans 오퍼레이션과 속성은 풀 방식을 사용함 -> MBeans 속성의 값이 변경되더라도 자동으로 알려주지 않아 JMX 클라이언트를 통해 봐야만 알 수 있음
MBeans는 JMX 크랄이언트에 알림을 푸시할 수 있는 방법이 있음
package tacos.tacos;
import java.util.concurrent.atomic.AtomicLong;
import javax.management.Notification;
import org.springframework.data.rest.core.event.AbstractRepositoryEventListener;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.jmx.export.notification.NotificationPublisher;
import org.springframework.jmx.export.notification.NotificationPublisherAware;
import org.springframework.stereotype.Service;
@Service
@ManagedResource
public class TacoCounter
extends AbstractRepositoryEventListener<Taco>
implements NotificationPublisherAware {
private AtomicLong counter;
private NotificationPublisher np;
public TacoCounter(TacoRepository tacoRepo) {
long initialCount = tacoRepo.count();
this.counter = new AtomicLong(initialCount);
}
@Override
public void setNotificationPublisher(NotificationPublisher np) {
this.np = np;
}
@Override
protected void onAfterCreate(Taco entity) {
counter.incrementAndGet();
}
@ManagedAttribute
public long getTacoCount() {
return counter.get();
}
@ManagedOperation
public long increment(long delta) {
long before = counter.get();
long after = counter.addAndGet(delta);
if ((after / 100) > (before / 100)) {
Notification notification = new Notification(
"taco.count", this,
before, after + "th taco created!");
np.sendNotification(notification);
}
return after;
}
}