本文转自JMX客户端及对commons-pool的监控
本文对原文进行梳理,梳理出一条使用JMX客户端对commons-pool监控的简单使用指南。
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
public class JmxC {
public static void main(String[] args) {
if (args.length > 0) {
if (args[0].equals("-l")) {
JmxC c = new JmxC();
c.m1();
} else if (args[0].equals("-p")) {
int id = Integer.valueOf(args[1]);
System.out.println("pid:" + id);
JmxC c = new JmxC();
if (args.length > 2 && args[2].equals("-n")) {
String name = args[3];
System.out.println("args name:" + name);
if (args.length > 4 && args[4].equals("-a")) {
String atts = args[5];
System.out.println("args atts:" + name);
c.processMbean(c.getConnectStrById(id), name, atts);
} else {
c.processMbean(c.getConnectStrById(id), name, null);
}
} else {
c.processMbean(c.getConnectStrById(id));
}
}
}
}
public void processMbean(String connectorAddress, String name, String att) {
if (null == connectorAddress)
return;
JMXConnector connector = null;
try {
System.out.println("conn:" + connectorAddress);
JMXServiceURL url = new JMXServiceURL(connectorAddress);
connector = JMXConnectorFactory.connect(url);
MBeanServerConnection mbeanConn = connector
.getMBeanServerConnection();
Set beanSet = mbeanConn.queryNames(null, null);
System.out.println("beanSet num:" + beanSet.size());
ObjectName n = new ObjectName(name);
MBeanInfo info = mbeanConn.getMBeanInfo(n);
if (null != info) {
if (null != att && !att.isEmpty()) {
String[] as = att.split(",");
List al = new LinkedList();
System.out.print(" time " + "\t");
for (String a : as) {
if (null != a && !a.isEmpty()) {
al.add(a);
System.out.print(a + "\t");
}
}
System.out.println();
SimpleDateFormat dateformat1 = new SimpleDateFormat(
"HH:mm:ss");
while (true) {
System.out.print(dateformat1.format(new Date()) + "\t");
for (String a : al) {
Object value = null;
if (!a.contains("-")) {
value = mbeanConn.getAttribute(n, a);
} else {
String[] at = a.split("-");
value = (long) mbeanConn.getAttribute(n, at[0])
- (long) mbeanConn.getAttribute(n,
at[1]);
}
System.out.print(value + "\t");
}
System.out.println();
Thread.sleep(1000);
}
} else {
MBeanAttributeInfo[] atts = info.getAttributes();
for (MBeanAttributeInfo attr : atts) {
Object value = mbeanConn
.getAttribute(n, attr.getName());
System.out.println(attr.getName() + "->" + value);
}
}
} else {
System.err.println("info is null");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (connector != null)
connector.close();
// break;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// ...
}
public void processMbean(String connectorAddress) {
if (null == connectorAddress)
return;
JMXConnector connector = null;
try {
System.out.println("conn:" + connectorAddress);
JMXServiceURL url = new JMXServiceURL(connectorAddress);
connector = JMXConnectorFactory.connect(url);
MBeanServerConnection mbeanConn = connector
.getMBeanServerConnection();
Set beanSet = mbeanConn.queryNames(null, null);
System.out.println("beanSet num:" + beanSet.size());
for (ObjectName name : beanSet) {
if (name.getDomain().equals("org.apache.commons.pool2")) {
System.out.println("name:" + name);
// ObjectInstance instance =
// mbeanConn.getObjectInstance(name);
MBeanInfo info = mbeanConn.getMBeanInfo(name);
MBeanAttributeInfo[] atts = info.getAttributes();
for (MBeanAttributeInfo attr : atts) {
Object value = mbeanConn.getAttribute(name,
attr.getName());
System.out.println(attr.getName() + "->" + value);
}
System.out.println();
System.out.println();
System.out.println();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (connector != null)
connector.close();
// break;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// ...
}
public String getConnectStrById(int pid) {
List vms = VirtualMachine.list();
int i = 0;
for (VirtualMachineDescriptor desc : vms) {
if (!desc.id().equals("" + pid)) {
continue;
}
VirtualMachine vm;
try {
System.out.println("desc:" + desc);
System.out.println("process id:" + desc.id());
vm = VirtualMachine.attach(desc);
} catch (Exception e) {
e.printStackTrace();
continue;
}
try {
Properties props = vm.getAgentProperties();
System.out.println("args:" + props.get("sun.jvm.args"));
for (Map.Entry
将上述代码编译,如果使用javac命令编译出错的话,建议先拷贝到eclipse,然后直接拿到编译后的.class文件。
2.1 先执行java cn/uce/uop/jmx/JmxC -l
解决办法:
将%JAVA_HOME%/jre/bin/attach.dll 拷贝到 %JAVA_HOME%/bin/目录下
再执行上述命令:
会列出当前的java进程,我们选择我们需要监控的进程,执行如下命令
2.2 javacn/uce/uop/jmx/JmxC -p 13260
pid:13260
desc:sun.tools.attach.WindowsAttachProvider@4617c264: 13260 cn.uce.uop.Test
process id:13260
args:-Dfile.encoding=UTF-8
conn:service:jmx:rmi://127.0.0.1/stub/rO0ABXNyAC5qYXZheC5tYW5hZ2VtZW50LnJlbW90ZS5ybWkuUk1JU2VydmVySW1wbF9TdHViAAAAAAAAAAICAAB4cgAaamF2YS5ybWkuc2VydmVyLlJlbW90ZVN0dWLp/tzJi+FlGgIAAHhyABxqYXZhLnJtaS5zZXJ2ZXIuUmVtb3RlT2JqZWN002G0kQxhMx4DAAB4cHc2AAtVbmljYXN0UmVmMgAACzEwLjIwMS4yLjYzAADh5wsYyZlaKbJNg8lsRAAAAWC1Eqi1gAEAeA==
beanSet num:20
name:org.apache.commons.pool2:type=GenericObjectPool,name=pool
NumActive->30
NumIdle->0
NumWaiters->1
TimeBetweenEvictionRunsMillis->30000
Fairness->false
Lifo->true
Closed->false
MaxTotal->30
MaxIdle->5
MinIdle->0
TestOnCreate->false
TestOnReturn->false
TestWhileIdle->true
NumTestsPerEvictionRun->-1
MinEvictableIdleTimeMillis->60000
TestOnBorrow->false
BlockWhenExhausted->true
MaxWaitMillis->-1
DestroyedByEvictorCount->0
MeanIdleTimeMillis->0
CreatedCount->30
DestroyedCount->0
CreationStackTrace->java.lang.Exception
at org.apache.commons.pool2.impl.BaseGenericObjectPool.(BaseGenericObjectPool.java:139)
at org.apache.commons.pool2.impl.GenericObjectPool.(GenericObjectPool.java:107)
at redis.clients.util.Pool.initPool(Pool.java:44)
at redis.clients.util.Pool.(Pool.java:23)
at redis.clients.jedis.JedisPool.(JedisPool.java:185)
at redis.clients.jedis.JedisPool.(JedisPool.java:162)
at redis.clients.jedis.JedisPool.(JedisPool.java:109)
at cn.uce.uop.Test.main(Test.java:19)
BorrowedCount->38
ReturnedCount->8
MeanActiveTimeMillis->0
DestroyedByBorrowValidationCount->0
RemoveAbandonedOnMaintenance->false
MaxBorrowWaitTimeMillis->41
LogAbandoned->false
AbandonedConfig->false
RemoveAbandonedOnBorrow->false
RemoveAbandonedTimeout->2147483647
MeanBorrowWaitTimeMillis->1
上述会列出通过jmx能监控的MBean属性
下一步我们就可以对重点参数进行动态监控
2.3 java cn/uce/uop/jmx/JmxC -p 13260 -n org.apache.commons.pool2:type=GenericObjectPool,name=pool -a NumActive,NumIdle,NumWaiters,BorrowedCount,ReturnedCount,BorrowedCount-ReturnedCount,CreatedCount,DestroyedCount,DestroyedByEvictorCount
注意,-n 后面的值都来源于2,2那个命令的输出