2014년 2월 18일 화요일

JMX - 기초

Benefits of using JMX
Using a Java-based solugion such as JMX offers JMX servral benefits, some of which are probably evident to you as a Java programmer, For example, Java is a portable language, so you can develop your application without regard to platform dependency, In addition to the benefits of the Java language, JMX has some persuasive advantages.

  1. Ease of use
  2. Leveraging existing technologies
  3. Componentization
  4. Alerts, events, and statistics

JMX Application의 기본 구조

JMX을 구성하는 요소는 다음 처럼 구분할 수 있다.
Manageable resource
A manageable resource is andy application, device, or existing entity that can be accessed or wrapped by Java. It is the entitiy that will be exposed for management by using JMX.

MBean
A Java class that meets certain naming and inheritance standards dictated by the JMX specification. Instantiated MBeans are Java objects that expose management interfaces for the mainpulation and access of manageable resources.

MBean server
An MBean server is a Java class  that manaages a group of MBeans. It is the heart of the JMX management environment-it acts as a registry for looking up MBeans.

JMX agent
A JMX agent is a Java process that provides a sset of services for managing a set of MBeans-it is the container for an MBean server.
Agents can expect to have a set of protocol adapters and connectors that enable remote and different clients to make use of the agent. Protocol adapters and connectors are Java classes, usually MBeans, which can internally map an outside protocol (like HTTP or SNMP) or expose the agent to remote connectivity (like RMI or Jini). This means JMX agents can be used by a variety of different management protocols and tools.



가장 간단한 JMX

package com.daddycat.blog.jmx;

public interface HelloMBean {
public void setMessage(String message);

public String getMessage();

public void sayHello();
}

HelloMBean은 하나의 Attribute와 하나의 Operation을 가집니다.
package com.daddycat.blog.jmx;

public class Hello implements HelloMBean {
private String message = null;

public Hello() {
message = "Hello, world";
}

public Hello(String message) {
this.message = message;
}

public void setMessage(String message) {
this.message = message;
}

public String getMessage() {
return message;
}

public void sayHello() {
System.out.println(message);
}
}



package com.daddycat.blog.jmx;

import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;

public class SimpleAgent {
private MBeanServer mbs = null;

public SimpleAgent() {

mbs = ManagementFactory.getPlatformMBeanServer();
// Unique identification of MBeans
Hello helloBean = new Hello();
ObjectName helloName = null;

try {
// Uniquely identify the MBeans and register them with the platform
// MBeanServer
helloName = new ObjectName("DADDYCAT:name=HelloBean");
mbs.registerMBean(helloBean, helloName);
} catch (Exception e) {
e.printStackTrace();
}
}

// Utility method: so that the application continues to run
private static void waitForEnterPressed() {
try {
System.out.println("Press  to continue...");
System.in.read();
} catch (Exception e) {
e.printStackTrace();
}
}

public static void main(String argv[]) {
                       SimpleAgent agent = new SimpleAgent();
System.out.println("SimpleAgent is running...");
SimpleAgent.waitForEnterPressed();
}
}



SimpleAgent을 실행한 후 JDK에 포함되어 있는 “Java VisualVM”을 실행합니다. 이 도구는 로컬이나 원격의 JMX에 접근할수 있게 해주는  JConsole 과 같은 기능을 합니다.



‘sayHello’ 클릭해보면 Eclipse Console에 반응이 옵니다.


“Hello, world”가 출력됐습니다.

리소스 변경에 Notification을 받는 MBean
이번에는 “Hello world”로 고정되어 있는 리소스가 변되는 경우 Agent가 Notification을 받는 JMX을 만들어 보겠습니다.

package com.daddycat.blog.jmx;

public interface HelloMBean {
public void setMessage(String message);

public String getMessage();

public void sayHello();
}

NotificationBroadcasterSupport”을 상속 받습니다. 리소스가 변경될 때 “sendNotification”이 실행되게 코드를 넣습니다.

public Notification(java.lang.String type, java.lang.Object source, long sequenceNumber,long timeStamp, java.lang.String message)



package com.daddycat.blog.jmx;

import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;

public class Hello extends NotificationBroadcasterSupport implements HelloMBean {
private String message = null;

public Hello() {
message = "Hello, world";
}

public Hello(String message) {
this.message = message;
}

public void setMessage(String message) {
this.message = message;
Notification notification = new Notification("DaddyCat.JMX.TEST", this, -1, System.currentTimeMillis(), message);
sendNotification(notification);
}

public String getMessage() {
return message;
}

public void sayHello() {
System.out.println(message);
}
}




package com.daddycat.blog.jmx;

import java.lang.management.ManagementFactory;

import javax.management.MBeanServer;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;


public class SimpleNotificationAgent implements NotificationListener {
private MBeanServer mbs = null;

public SimpleNotificationAgent() {

// Get the platform MBeanServer
mbs = ManagementFactory.getPlatformMBeanServer();
// Unique identification of MBeans
Hello helloBean = new Hello();
ObjectName helloName = null;

try {
// Uniquely identify the MBeans and register them with the platform
// MBeanServer
helloName = new ObjectName("DADDYCAT:name=HelloBeanForNotification");
mbs.registerMBean(helloBean, helloName);
helloBean.addNotificationListener(this, null, null);
} catch (Exception e) {
e.printStackTrace();
}
}

// Utility method: so that the application continues to run
private static void waitForEnterPressed() {
try {
System.out.println("Press  to continue...");
System.in.read();
} catch (Exception e) {
e.printStackTrace();
}
}

public static void main(String argv[]) {
SimpleNotificationAgent agent = new SimpleNotificationAgent();
System.out.println("SimpleNotificationAgent is running...");
SimpleNotificationAgent.waitForEnterPressed();
}

@Override
public void handleNotification(Notification notification, Object handback) {
System.out.println("Receiving notification....");
System.out.println(notification.getType());
System.out.println(notification.getMessage());
}
}

MBean에 agent을 등록해줍니다.
helloBean.addNotificationListener(this, null, null);

그리고 Notification을 받을 “handleNotification” 메서드를 Override해 줍니다.


Agent을 실행후 다시 VisualVM에가서 이번에는 리소스을 수정해보면 Notification이 발생함을 볼수 있습니다.



HTMLAdaptor 사용하기
지금까지는 VisualVM을 이용해서 MBean에 접근했지만 HTMLAdaptor을 이용해서 브라우저에서 접근가능하도록 해봅니다. HTMLAdaptor는 JDK에 포함되어 있지 않기 때문에 아래 주소에서 별도로 다운로드 받아서 사용해야 합니다.

Agent에 HTMLAdaptor을 MBServer에 등록해주는 코드만 넣으면 됩니다.

package com.daddycat.blog.jmx;

import java.lang.management.ManagementFactory;

import javax.management.MBeanServer;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;

import com.sun.jdmk.comm.HtmlAdaptorServer;


public class HTMLAdaptorAgent implements NotificationListener {
private MBeanServer mbs = null;

public HTMLAdaptorAgent() {

// Get the platform MBeanServer
mbs = ManagementFactory.getPlatformMBeanServer();
HtmlAdaptorServer adapter = new HtmlAdaptorServer();
// Unique identification of MBeans
Hello helloBean = new Hello();
ObjectName helloName = null;
ObjectName htmlAdaptorName = null;

try {
// Uniquely identify the MBeans and register them with the platform
// MBeanServer
helloName = new ObjectName("DADDYCAT:name=HelloBean");
mbs.registerMBean(helloBean, helloName);
helloBean.addNotificationListener(this, null, null);
htmlAdaptorName =
new ObjectName( "HTMLAdaptorAgent:name=htmladapter,port=9092" );
adapter.setPort(9092);
mbs.registerMBean(adapter, htmlAdaptorName);
adapter.start();
} catch (Exception e) {
e.printStackTrace();
}
}

// Utility method: so that the application continues to run
private static void waitForEnterPressed() {
try {
System.out.println("Press  to continue...");
System.in.read();
} catch (Exception e) {
e.printStackTrace();
}
}

public static void main(String argv[]) {
                       HTMLAdaptorAgent agent = new HTMLAdaptorAgent();
System.out.println("HTMLAdaptorAgent is running...");
HTMLAdaptorAgent.waitForEnterPressed();
}

@Override
public void handleNotification(Notification notification, Object handback) {
System.out.println("Receiving notification....");
System.out.println(notification.getType());
System.out.println(notification.getMessage());
}
}


http://localhost:9092 접근하면 브라우저에서 MBean을 확인할 수 있습니다.




다음에는 Connector을 이용하는 방법을 살펴보기로 하겠습니다.

댓글 없음:

댓글 쓰기

블록체인 개요 및 오픈소스 동향

블록체인(block chain) 블록체인은 공공 거래장부이며 가상 화폐로 거래할때 발생할때 발생할 수 있는 해킹을 막는 기술. 분산 데이터베이스의 한 형태로, 지속적으로 성장하는 데이터 기록 리스트로서 분산 노드의 운영자에 의한 임의 조작이 불가...