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 SetgetObjectNames(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"); } }
댓글 없음:
댓글 쓰기