JMX客户端及对commons-pool的监控

    本文转自JMX客户端及对commons-pool的监控

    本文对原文进行梳理,梳理出一条使用JMX客户端对commons-pool监控的简单使用指南。

    

生产线上,我们的服务基本都是在linux环境下部署的,当高并发的时候,机器的负载是比较高的,所以我们只能在linux机器上执行一些简单的命令行工具,如jps,jstack,jinfo等,像重量级的jconsole,jvisualvm这些首先需要桌面环境才能观看,服务器肯定是没有开启X client的,所以只能通过jmx在远程客户端观看,但这种情况下,势必会对本机造成一些不必要的资源占用,如网络带宽等。但是想mbean这些对象的监控目前又只能通过jconsole,jvisualvm这些jmx客户端访问,想要在本机以命令行的方式查看还是比较困难的。本文的目的就是介绍下怎么在linux服务器下以命令下的方式进行jmx监控。

1、代码
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 entry : props.entrySet()) {
					// System.out.println(entry.getKey() + "->" +
					// entry.getValue());
				}

				String connectorAddress = props
						.getProperty("com.sun.management.jmxremote.localConnectorAddress");
				if (connectorAddress == null) {
					System.out
							.println("connectorAddress  is  null,and continue search");
					props = vm.getSystemProperties();
					String home = props.getProperty("java.home");

					// Normally in ${java.home}/jre/lib/management-agent.jar but
					// might
					// be in ${java.home}/lib in build environments.

					String agent = home + File.separator + "jre"
							+ File.separator + "lib" + File.separator
							+ "management-agent.jar";
					File f = new File(agent);
					if (!f.exists()) {
						agent = home + File.separator + "lib" + File.separator
								+ "management-agent.jar";
						f = new File(agent);
						if (!f.exists()) {
							throw new IOException("Management agent not found");
						}
					}
					agent = f.getCanonicalPath();
					vm.loadAgent(agent, "com.sun.management.jmxremote");
					props = vm.getAgentProperties();
					connectorAddress = props
							.getProperty("com.sun.management.jmxremote.localConnectorAddress");
					if (connectorAddress == null) {
						System.out.println("connectorAddress  is  null");
					}

				}
				return connectorAddress;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		System.out.println("return null");
		return null;
	}

	public void m1() {
		List vms = VirtualMachine.list();
		int i = 0;
		for (VirtualMachineDescriptor desc : vms) {
			System.out.println();
			System.out.println();
			System.out.println("------" + i++ + "----------------");
			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;
			}
			JMXConnector connector = null;
			try {
				Properties props = vm.getAgentProperties();
				System.out.println(props.get("sun.jvm.args"));
				for (Map.Entry entry : props.entrySet()) {
					// System.out.println(entry.getKey() + "->" +
					// entry.getValue());
				}

				String connectorAddress = props
						.getProperty("com.sun.management.jmxremote.localConnectorAddress");
				if (connectorAddress == null) {
					System.out
							.println("connectorAddress  is  null,and continue search");
					props = vm.getSystemProperties();
					String home = props.getProperty("java.home");

					// Normally in ${java.home}/jre/lib/management-agent.jar but
					// might
					// be in ${java.home}/lib in build environments.

					String agent = home + File.separator + "jre"
							+ File.separator + "lib" + File.separator
							+ "management-agent.jar";
					File f = new File(agent);
					if (!f.exists()) {
						agent = home + File.separator + "lib" + File.separator
								+ "management-agent.jar";
						f = new File(agent);
						if (!f.exists()) {
							throw new IOException("Management agent not found");
						}
					}
					agent = f.getCanonicalPath();
					vm.loadAgent(agent, "com.sun.management.jmxremote");
					props = vm.getAgentProperties();
					connectorAddress = props
							.getProperty("com.sun.management.jmxremote.localConnectorAddress");
					if (connectorAddress == null) {
						System.out.println("connectorAddress  is  null");
						continue;
					}
				}
				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());
				// ...
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					if (connector != null)
						connector.close();
					// break;
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

}
将上述代码编译,如果使用javac命令编译出错的话,建议先拷贝到eclipse,然后直接拿到编译后的.class文件。

2、使用上述工具来监控commons-pool
1)首先我们将编译后的class文件存放在
JMX客户端及对commons-pool的监控_第1张图片

然后我们先cmd进入到 jedis目录:

2.1 先执行java  cn/uce/uop/jmx/JmxC -l


解决办法:

将%JAVA_HOME%/jre/bin/attach.dll 拷贝到 %JAVA_HOME%/bin/目录下

再执行上述命令:

JMX客户端及对commons-pool的监控_第2张图片

会列出当前的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那个命令的输出

JMX客户端及对commons-pool的监控_第3张图片



你可能感兴趣的:(JMX客户端及对commons-pool的监控)