application 에서 감시할 항목을 MBean 으로 jmx 에 노출 시켜 application 을 모니터링 할 수 있다.
jmx (2번 3번은 은 하나의 파일로 super - sub class 형식으로 작성가능)
1. mbean interface 생성
2. mbean 구현체 생성
3. mbean 구현체 jmx 에 등록 코드 작성
4. java 실행 with jmx option
5. jvisualvm 확인
* 표준 MBean Interface 생성 (※ 주의 interface suffix -MBean)
- MBean 인터페이스는 감시할 항목 정의
public interface MonitoringMBean {
long getExecuteTime();
long getPollingCount();
long getChannelPercentage();
}
* MBean Interface 구현
- 구현체에서 jmx 에 등록할 항목의 값을 return 한다.
- interface 의 구현체의 접미사 MBean 을 제외하고 파일명이 같아야 한다.
public class Monitoring implements MonitoringMBean {
public long getExecuteTime() {
return MonitoringCounter.getInstance().getExecuteTime();
}
public long getPollingCount() {
return MonitoringCounter.getInstance().getPollingCount();
}
public long getChannelPercentage() {
return MonitoringCounter.getInstance().getChannelPercentage();
}
}
* 모니터링 값 설정
- 여러 객체에서 MonitoringMBean 구현체인 Monitoring 객체에 값을 지정 하려면 싱글톤 방식으로 값을 전달해야 한다.
public class MonitoringCounter {
private static MonitoringCounter counter;
private long executeTime;
private long pollingCount;
private long channelPercentage;
private MonitoringCounter() {
}
public static MonitoringCounter getInstance() {
if(counter == null) {
counter = new MonitoringCounter();
}
return counter;
}
public long getExecuteTime() {
return executeTime;
}
public void setExecuteTime(long executeTime) {
this.executeTime = executeTime;
}
public long getPollingCount() {
return pollingCount;
}
public void setPollingCount(long pollingCount) {
this.pollingCount = pollingCount;
}
public long getChannelPercentage() {
return channelPercentage;
}
public void setChannelPercentage(long channelPercentage) {
this.channelPercentage = channelPercentage;
}
}
* MBean 등록
public class MonitoringExporter {
private Monitoring monitoring;
public MonitoringExporter() {
try {
this.monitoring = new Monitoring();
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
// new ObjectName("임의의 MBean 명 :type=임의의 Type명");
ObjectName jmxObjectName = new ObjectName("SomeApp:type=SomeType");
server.registerMBean(monitoring, jmxObjectName);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
-Dcom.sun.management.jmxremote.port=9999(임의의 포트 - 사용자 설정)
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
MonitoringExporter exporter = new MonitoringExporter();
}
}
* application 실행 java option
-Dcom.sun.management.jmxremote.port=9999 (임의의 포트)
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
* application
public class SomeApp {
private Random rand;
public SomeApp() {
this.rand = new Random();
}
public void run() {
System.out.println("do something.....");
MonitoringCounter.getInstance().setChannelPercentage(rand.nextLong());
MonitoringCounter.getInstance().setExecuteTime(rand.nextLong());
MonitoringCounter.getInstance().setPollingCount(rand.nextLong());
}
public static void main(String[] args) throws Exception {
MonitoringExporter.main(null);
SomeApp someApp = new SomeApp();
while(true) {
someApp.run();
Thread.sleep(1000);
}
}
}
* jvisualvm 확인
- MBeans 항목은 별도 jvisualvm 플러그인 설치
visualvm > tools > plugins > Avaliable Plugins > VisualVM-MBeans
또는 http://visualvm.java.net/pluginscenters.html 에서 현재 visualvm 버전의 plugin search
public class JMXReader {
private MBeanServerConnection server;
/**
* local connection
*/
public JMXReader() {
this.server = ManagementFactory.getPlatformMBeanServer();
}
/**
* remote connection
* remote 정의
* 같은 서버(localhost) 이라도 java 로 실행시키는 app 이 다를 경우 remote 로 이해해야함
* @param url
* @throws IOException
*/
public JMXReader(String url) throws IOException {
JMXServiceURL serviceURL = new JMXServiceURL(url);
/* java.io.IOException: The client has been closed. 발생 - 발생이유는 좀더 분석이 필요함
try (JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceURL)) {
this.server = jmxConnector.getMBeanServerConnection();
}
*/
JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceURL);
this.server = jmxConnector.getMBeanServerConnection();
}
public String[] getDomains() {
try {
return this.server.getDomains();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
*
* @param objectName 정규식 및 null 가능
* null = all
* *:* = all
* SomeApp:*
* Some*:type:S*
*
* @return
*/
public Set getObjectNames(ObjectName objectName) {
try {
return Sets.newHashSet(
Optional.ofNullable(this.server.queryNames(
objectName
,null
)).orElse(Sets.newHashSet()));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
*
* @param objectName MBean
* @return
*/
public List getAttributes(ObjectName objectName) {
MBeanInfo info = null;
try {
info = this.server.getMBeanInfo(objectName);
} catch (Exception e) {
e.printStackTrace();
}
return Arrays.stream(Optional.ofNullable(info).map(MBeanInfo::getAttributes).orElse(new MBeanAttributeInfo[]{null})).map(MBeanAttributeInfo::getName).collect(toList());
}
/**
*
* @param objectName MBean
* @param attrName MBean 항목
* @return
*/
public Object getAttributeValue(ObjectName objectName, String attrName) {
try {
return this.server.getAttribute(objectName, attrName);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) throws MalformedObjectNameException, IOException {
// local
JMXReader local = new JMXReader();
System.out.println(local.getAttributeValue(new ObjectName("java.lang:type=GarbageCollector,name=PS MarkSweep"), "Name"));
System.out.println("-------------------------- local end");
// remote
JMXReader remote = new JMXReader("service:jmx:rmi:///jndi/rmi://127.0.0.1:9999/jmxrmi");
Arrays.stream(remote.getDomains()).forEach(System.out::println);
System.out.println("-------------------------- domains end");
remote.getObjectNames(new ObjectName("*:*")).forEach(System.out::println);
System.out.println("-------------------------- objectNames end");
remote.getAttributes(new ObjectName("SomeApp:type=SomeType")).forEach(System.out::println);
System.out.println("-------------------------- attributes of SomeApp MBean end");
System.out.println(remote.getAttributeValue(new ObjectName("SomeApp:type=SomeType"), "ExecuteTime"));
System.out.println("-------------------------- attribute value of SomeApp MBean ExecuteTime Attribute end");
}
}

댓글 없음:
댓글 쓰기