반응형
1) Server
package org.jmxserver.main;
import java.rmi.registry.LocateRegistry;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import org.jmxserver.inter.CPUModel;
public class Server {
private MBeanServer mbs = null;
public Server() {
mbs = MBeanServerFactory.createMBeanServer("");
CPUModel model = new CPUModel();
ObjectName name = null;
JMXServiceURL serviceURL = null;
try {
System.setProperty("java.rmi.server.hostname","192.168.0.24");
LocateRegistry.createRegistry(7777); //port
serviceURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://192.168.0.24:7777/server");
name = new ObjectName("CPUModel:name=CPUModel");
JMXConnectorServer connector = JMXConnectorServerFactory.newJMXConnectorServer(serviceURL, null, mbs);
mbs.registerMBean(model, name);
connector.start();
}
catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String argv[]) {
new Server();
System.out.println("Server Starting...");
}
}
package org.jmxserver.inter;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CPUModel implements CPUModelMBean {
private final long threadId;
private long lastCpuTime = 0;
private long lastPoll = 0;
public double getCput() {
double cpu = -1;
try {
// start up the command in child process
String cmd = "top -n 2 -b -d 0.2";
Process child = Runtime.getRuntime().exec(cmd);
// hook up child process output to parent
InputStream lsOut = child.getInputStream();
InputStreamReader r = new InputStreamReader(lsOut);
BufferedReader in = new BufferedReader(r);
// read the child process' output
String line;
int emptyLines = 0;
while (emptyLines < 3) {
line = in.readLine();
if (line.length() < 1)
emptyLines++;
}
in.readLine();
in.readLine();
line = in.readLine();
System.out.println("Parsing line " + line);
String delims = "%";
String[] parts = line.split(delims);
System.out.println("Parsing fragment " + parts[0]);
delims = " ";
parts = parts[0].split(delims);
cpu = Double.parseDouble(parts[parts.length - 1]);
} catch (Exception e) { // exception thrown
System.out.println("Command failed!");
}
return cpu;
}
@Override
public String getString() {
// TODO Auto-generated method stub
return "hi";
}
@Override
public Object getObject() {
// TODO Auto-generated method stub
return new CPUModel();
}
@Override
public List<String> getList() {
// TODO Auto-generated method stub
return new ArrayList<String>();
}
@Override
public String[] getArray() {
// TODO Auto-generated method stub
return new String[10];
}
@Override
public Map<String, Object> getMap() {
// TODO Auto-generated method stub
return new HashMap<String, Object>();
}
/**
* Creates a CpuStats object for a single thread.
*
* @param threadId The id of the thread to monitor
*
*/
public CPUModel(long threadId) {
this.threadId = threadId;
lastCpuTime = getTotalTime();
lastPoll = System.nanoTime();
}
/**
* Creates a CpuStatus object for all threads. The supplied statistics affect
* all threads in the current VM.
*/
public CPUModel() {
threadId = -1;
lastCpuTime = getTotalTime();
lastPoll = System.nanoTime();
}
public long getRelativeTime() {
long currentCpuTime = getTotalTime();
long ret = currentCpuTime - lastCpuTime;
lastCpuTime = currentCpuTime;
return ret;
}
public double getUsage() {
long timeBefore = this.lastPoll;
lastPoll = System.nanoTime();
long relTime = getRelativeTime();
return Math.max((double) relTime / (double) (lastPoll - timeBefore), 0.0);
}
public long getTotalTime() {
if (threadId == -1) {
long cpuTime = 0;
for (long id : ManagementFactory.getThreadMXBean().getAllThreadIds()) {
cpuTime += ManagementFactory.getThreadMXBean().getThreadCpuTime(id);
}
return cpuTime;
} else {
return ManagementFactory.getThreadMXBean().getThreadCpuTime(threadId);
}
}
}
package org.jmxserver.inter;
import java.util.List;
import java.util.Map;
public interface CPUModelMBean {
public long getRelativeTime();
public double getUsage();
public long getTotalTime();
public double getCput();
public String getString();
public Object getObject();
public List<String> getList();
public String[] getArray();
public Map<String, Object> getMap();
}
2) Client
package org.mbeans.hello;
import java.util.Arrays;
import javax.management.JMX;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.RuntimeErrorException;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import org.jmxserver.inter.CPUModelMBean;
public class CPUClient {
public static void main(String[] args) {
foo();
}
public static void foo() {
try {
System.out.println("server init...");
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://192.168.0.24:7777/server");
System.out.println("connector init...");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
System.out.println("connection init...");
// Get an MBeanServerConnection
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
// Get domains from MBeanServer
String domains[] = mbsc.getDomains();
Arrays.sort(domains);
for (String domain : domains) {
System.out.println(domain);
}
// JMXServer에서 등록한 ObjectName 생성
ObjectName mbeanName = new ObjectName("CPUModel:name=CPUModel");
// Create a dedicated proxy for the MBean instead of
// going directly through the MBean server connection
CPUModelMBean model = JMX.newMBeanProxy(mbsc, mbeanName, CPUModelMBean.class, true);
// start job
System.out.println("getRelativeTime = " + model.getRelativeTime());
System.out.println("getUsage = " + model.getUsage());
System.out.println("getTotalTime = " + model.getTotalTime());
System.out.println("getCput = " + model.getCput());
System.out.println("getString = " + model.getString());
System.out.println("getObject = " + model.getObject()); // 오브젝트 클래스에 대한 마샬링이 필요
System.out.println("getList = " + model.getList());
System.out.println("getArray = " + model.getArray());
System.out.println("getMap = " + model.getMap());
} catch (RuntimeErrorException e) {
System.out.println("Error --->" + e);
e.printStackTrace();
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
}
- Server 측의 MBeans에 해당하는 CPUModel과 CPUModelMBeans 클래스와 인터페이스를 Client 측에서도 똑같이 구현 해주어야 한다.
- 포트와 아이피 주소는 임의로 지정해주어야 한다.
- 필자는 Server를 Oracle 가상머신에 우분투를 설치한 후 기동했고, Client는 Window에서 기동했다.
3) 실행 결과
Client 측
server init...
connector init...
connection init...
JMImplementation
org.jmxserver.inter.CPUModel
getRelativeTime = 180594092
getUsage = 7.489918770553646E-4
getTotalTime = 287235313
getCput = -1.0
getString = hi
getObject = org.jmxserver.inter.CPUModel@446cdf90
getList = []
getArray = [Ljava.lang.String;@22d8cfe0
getMap = {}
Server 측
4) 코드 해석
- 위 코드는 Server 측의 CPU 상태를 확인하는 기능과 Server, Client에 String, Map, List, Object 등의 변수 타입들이 잘 받아지는지 확인하기 위한 코드이다.
5) error unmarshalling return; nested exception is: no security manager: RMI class loader disabled 에러 발생 시의 조치
- error unmarshalling return; nested exception is: no security manager: RMI class loader disabled 에러 발생 했을 때의 조치다.
- 서버에서 반환하는 Object 클래스를 받을 형태가 클라이언트에서 정의되지 않아서 발생하는 문제 => 서버에서 돌려주는 Object의 패키지 이름과 클래스 명을 갖게 해야함. Ex) 서버에서 정의된 이름이 org.jmxserver.inter.CPUModel 이면 클라이언트에서도 똑같이 정의해주어야 함.
- 서버 측에서의 클래스가 아래와 같다면,
- 클라이언트 측에서도 클래스와 패키지를 아래와 같이 지정해주어야 한다.
반응형
'Java > JMX' 카테고리의 다른 글
[오류해결] javax.management.NotCompliantMBeanException: (0) | 2020.08.24 |
---|---|
[Java] JMX MBean을 이용한 모니터링(Client, Server) (0) | 2020.05.08 |
[JAVA] JMX 예제 코드 및 jmxremote properties 설정 (0) | 2020.03.18 |
[JAVA] JMX의 mBean이란? JMX는 무엇인지? (0) | 2020.03.18 |