前言
JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架。JMX是一套标准的代理和服务,实际上,用户可以在任何Java应用程序中使用这些代理和服务实现管理。
应用场景:中间件tomcat和weblogic都支持jmx,需要对其进行配置即可通过接口或者jdk自带的工具jcode获取监控数据
下面通过程序和jcode工具展示数据
一、tomcat和weblogic配置jmx
这里提供tomcat和weblogic的jmx配置和第三方调用,was的待研究
1.tomcat配置
修改tomcat/bin目录下的catalina.bat(win)/catalina.sh(linux),
新增
set JAVA_OPTS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9008 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
**9008 **是jmx远程的端口,Dcom.sun.management.jmxremote.authenticate=false,表示不需要登录;
2.weblogic配置
windows下修改
E:\path\weblogic\weblogic12.2.1.4\user_projects\domains\base_domain\bin
即域名目录下的base_domain\bin\setDomainEnv.cmd
linux下修改
setDomainEnv.sh
新增
set JAVA_OPTIONS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9008 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
注意 win的set命令对应Linux下的export命令,同时tomcat的是JAVA_OPTS,weblogic的是JAVA_OPTIONS。
二、jcode远程调用jmx
进入java_home/bin目录,打开jcode.exe
可以通过本地进程选择打开,也可以通过远程连接
service:jmx:rmi:///jndi/rmi://localhost:9008/jmxrmi
这里不仅可以获取服务器的数据,也可以获取运行的性能数据,做到监控功能
三、java程序调用
下面通过程序获取MBean数据
1.获取所有的对象
package tomcat;
import java.util.*;
import javax.management.*;
import javax.management.remote.*;
public class JmxTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
// 这里的url是在上图中输入的url
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9008/jmxrmi");
// Map<String, String[]> map = new HashMap();
// String[] credentials=new String[] {"monitorRole","QED"};
// map.put("jmx.remote.credentials",credentials);
JMXConnector conn = JMXConnectorFactory.connect(url);
System.out.println("JMXConnector=" + conn.toString());
String id = conn.getConnectionId();
System.out.println("Connection Id=" + id);
MBeanServerConnection mbsc = conn.getMBeanServerConnection();
String domains[] = mbsc.getDomains();
System.out.println("# of domains=" + domains.length);
for (int i = 0; i < domains.length; i++) {
System.out.println("Domain[" + i + "]=" + domains[i]);
}
Set<ObjectInstance> MBeanset = mbsc.queryMBeans(null, null);
System.out.println("MBeanset.size() : " + MBeanset.size());
Iterator<ObjectInstance> MBeansetIterator = MBeanset.iterator();
while (MBeansetIterator.hasNext()) {
ObjectInstance objectInstance = (ObjectInstance) MBeansetIterator.next();
ObjectName objectName = objectInstance.getObjectName();
String canonicalName = objectName.getCanonicalName();
System.out.println("objectName >>>>>>>>>>: " + objectName);
System.out.println("canonicalName : " + canonicalName);
// 在上图中,有Catalina:type=Server的port的值8005,运行程序后,在控制台能看到获取成功
if (objectName.toString().equals("Catalina:type=Server")) {
// Get details of cluster MBeans
String s = mbsc.getAttribute(objectName, "port").toString();
System.out.println("=========================================");
System.out.println(s);
System.out.println("=========================================");
}
// String canonicalKeyPropList=objectName.getCanonicalKeyPropertyListString();
}
conn.close();
} catch (Exception ex) {
System.out.println("Illegal Argument Exception: " + ex);
}
}
}
Set<ObjectInstance> MBeanset = mbsc.queryMBeans(null, null);
是获取所有的对象。
import java.util.*;
import javax.management.*;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.remote.*;
public class JmxValue {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
String KeyName = "";
String objectName1 = "";
String attributeName = "";
String attributeKey = "";
String value = "";
objectName1 = "java.lang:type=Memory";
attributeName = "NonHeapMemoryUsage";
attributeKey = "init";
objectName1 = "java.lang:name=PS Eden Space";
attributeName = "MemoryPool";
attributeKey = "";
value = GetValueByKey(objectName1, attributeName, attributeKey);
System.out.println("value>>>>>>>>>>>>>>>>>"+value);
// 这里的url是在上图中输入的url
// JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9008/jmxrmi");
// // Map<String, String[]> map = new HashMap();
// // String[] credentials=new String[] {"monitorRole","QED"};
// // map.put("jmx.remote.credentials",credentials);
//
// JMXConnector conn = JMXConnectorFactory.connect(url);
// System.out.println("JMXConnector=" + conn.toString());
// String id = conn.getConnectionId();
// System.out.println("Connection Id=" + id);
//
// MBeanServerConnection mbsc = conn.getMBeanServerConnection();
// String domains[] = mbsc.getDomains();
// System.out.println("# of domains=" + domains.length);
// for (int i = 0; i < domains.length; i++) {
// System.out.println("Domain[" + i + "]=" + domains[i]);
// }
//
// Set<ObjectInstance> MBeanset = mbsc.queryMBeans(null, null);
// System.out.println("MBeanset.size() : " + MBeanset.size());
// Iterator<ObjectInstance> MBeansetIterator = MBeanset.iterator();
// while (MBeansetIterator.hasNext()) {
// ObjectInstance objectInstance = (ObjectInstance) MBeansetIterator.next();
// ObjectName objectName = objectInstance.getObjectName();
// String canonicalName = objectName.getCanonicalName();
//
// System.out.println("canonicalName : " + canonicalName);
// if(canonicalName.contains("PS Old Gen")) {
// System.out.println("mbsc>>>>>>>>>>>>>>>>>>"+mbsc);
// }
// // 在上图中,有Catalina:type=Server的port的值8005,运行程序后,在控制台能看到获取成功
// if (objectName.toString().equals("Catalina:type=Server")) {
// // Get details of cluster MBeans
// String s = mbsc.getAttribute(objectName, "port").toString();
// System.out.println("=========================================");
// System.out.println(s);
// System.out.println("=========================================");
// }
// // String canonicalKeyPropList=objectName.getCanonicalKeyPropertyListString();
// }
// conn.close();
} catch (Exception ex) {
System.out.println("Illegal Argument Exception: " + ex);
}
}
private static String GetValueByKey(String objectName, String attributeName, String attributeKey) throws Exception {
JMXConnector conn = null;
try {
String _value = "";
objectName = "java.lang:type=MemoryPool,name=PS Eden Space";
attributeName = "Usage";
attributeKey = "";
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9008/jmxrmi");
// Map<String, String[]> map = new HashMap();
// String[] credentials=new String[] {"monitorRole","QED"};
// map.put("jmx.remote.credentials",credentials);
conn = JMXConnectorFactory.connect(url);
System.out.println("JMXConnector=" + conn.toString());
MBeanServerConnection mbsc = conn.getMBeanServerConnection();
String domains[] = mbsc.getDomains();
String id = conn.getConnectionId();
System.out.println("Connection Id=" + id);
// Set<ObjectInstance> MBeanset = mbsc.queryMBeans("java.lang:type=Memory",
// null);
// Set<ObjectInstance> MBeanset = mbsc.queryMBeans(null, null);
ObjectName _objectName = new ObjectName(objectName);
if (attributeKey.equals("")) {
CompositeDataSupport support = (CompositeDataSupport) mbsc.getAttribute(_objectName, attributeName);
System.out.println("init:"+support.get("committed"));
} else {
javax.management.openmbean.CompositeData data = (javax.management.openmbean.CompositeData) mbsc
.getAttribute(_objectName, attributeName);
_value = data.get(attributeKey).toString();
}
return _value;
} catch (Exception ex) {
System.out.println("Illegal Argument Exception: " + ex);
throw ex;
} finally {
if (conn != null) {
conn.close();
}
}
}
}
上面代码是获取
JVM中PS Eden Space的数据,至于如何获取,需要看
这个帮助文档。
右侧的ObjectName就是PS Eden Space的对应的对象名称,attributeName是属性名称,
这个是PS Eden Space的使用情况,返回的对象是
这部分是对应的各部分的数据