使用JMX监控Zookeeper状态Java API
一、背景
上一篇通过Java自带的JConsole来获取zookeeper状态。主要有几个不方便的地方,zk集群一般会部署3或者5台,在多个JConsole窗口中切换比较麻烦,各个zk服务及历史数据之间,不能直观比较。一般会做一个WEB管理页面来展示集群状态,设置报警阀值来做报警。
二、JVM平台提供Mbeans
在Java5.0以上版本,有一组API可以让Java应用程序和允许的工具监视和管理Java虚拟机(JVM)和虚拟机所在的本机操作系统。该组API在java.lang.management包。可以通过这些API可以监控local端JVM,同时也可以监控远端JVM。
通过静态工厂方法获取MXBean实例,从本地访问正在运行的虚拟机的MXBean接口。这些Bean我们从ManagementFactory类中定义的静态方法获取;如ManagementFactory.getOperatingSystemMXBean();其中不足就是只能获取本地的JVM状态。无法获取远程的虚拟机数据。
- ClassLoadingMXBeanJava虚拟机的类加载系统
- CompilationMXBeanJava虚拟机的编译系统
- MemoryMXBeanJava虚拟机的内存系统
- RuntimeMXBeanJava虚拟机的运行时系统
- OperatingSystemMXBeanJava虚拟机在其上运行的操作系统
- GarbageCollectorMXBeanJava虚拟机中的垃圾回收器
- MemoryManagerMXBeanJava虚拟机中的内存管理器
- MemoryPoolMXBeanJava虚拟机中的内存池
三、Zookeeper提供出来的Mbeans
构造MXBean代理实例,通过代理将方法调用转发到给定的MBeanServe。JConsole能够监控的项目,通过API都能获取到。
具体代码如下:
importjava.io.IOException;
importjava.lang.management.ClassLoadingMXBean;
importjava.lang.management.CompilationMXBean;
importjava.lang.management.ManagementFactory;
importjava.lang.management.OperatingSystemMXBean;
importjava.lang.management.ThreadMXBean;
importjava.util.ArrayList;
importjava.util.Arrays;
importjava.util.Collections;
importjava.util.HashMap;
importjava.util.Iterator;
importjava.util.List;
importjava.util.Map;
importjava.util.Set;
importjavax.management.InstanceNotFoundException;
importjavax.management.IntrospectionException;
importjavax.management.JMX;
importjavax.management.MBeanServerConnection;
importjavax.management.MalformedObjectNameException;
importjavax.management.ObjectName;
importjavax.management.ReflectionException;
importjavax.management.remote.JMXConnector;
importjavax.management.remote.JMXConnectorFactory;
importjavax.management.remote.JMXServiceURL;
importorg.apache.zookeeper.server.ConnectionMXBean;
importorg.apache.zookeeper.server.DataTreeMXBean;
importorg.apache.zookeeper.server.ZooKeeperServerMXBean;
publicclassZkJMXTest{
staticJMXConnectorconnector;
/**
*@paramargs
*@throwsIOException
*@throwsMalformedObjectNameException
*@throwsInstanceNotFoundException
*@throwsReflectionException
*@throwsIntrospectionException
*/
publicstaticvoidmain(String[]args)throwsIOException,MalformedObjectNameException,
InstanceNotFoundException,IntrospectionException,ReflectionException{
OperatingSystemMXBeanosbean=ManagementFactory.getOperatingSystemMXBean();
System.out.println("体系结构:"+osbean.getArch());//操作系统体系结构
System.out.println("处理器核数:"+osbean.getAvailableProcessors());///核数
System.out.println("名字:"+osbean.getName());//名字
System.out.println(osbean.getVersion());//操作系统版本
ThreadMXBeanthreadBean=ManagementFactory.getThreadMXBean();
System.out.println("活动线程:"+threadBean.getThreadCount());//总线程数
ClassLoadingMXBeanclassLoadingMXBean=ManagementFactory.getClassLoadingMXBean();
CompilationMXBeancompilationMXBean=ManagementFactory.getCompilationMXBean();
System.out.println("===========");
//通过MBeanServer间接地访问MXBean接口
MBeanServerConnectionmbsc=createMBeanServer("192.168.1.100","9991","controlRole","123456");
//操作系统
ObjectNameos=newObjectName("java.lang:type=OperatingSystem");
System.out.println("体系结构:"+getAttribute(mbsc,os,"Arch"));//体系结构
System.out.println("处理器核数:"+getAttribute(mbsc,os,"AvailableProcessors"));//核数
System.out.println("总物理内存:"+getAttribute(mbsc,os,"TotalPhysicalMemorySize"));//总物理内存
System.out.println("空闲物理内存:"+getAttribute(mbsc,os,"FreePhysicalMemorySize"));//空闲物理内存
System.out.println("总交换空间:"+getAttribute(mbsc,os,"TotalSwapSpaceSize"));//总交换空间
System.out.println("空闲交换空间:"+getAttribute(mbsc,os,"FreeSwapSpaceSize"));//空闲交换空间
System.out.println("操作系统:"+getAttribute(mbsc,os,"Name")+getAttribute(mbsc,os,"Version"));//操作系统
System.out.println("提交的虚拟内存:"+getAttribute(mbsc,os,"CommittedVirtualMemorySize"));//提交的虚拟内存
System.out.println("系统cpu使用率:"+getAttribute(mbsc,os,"SystemCpuLoad"));//系统cpu使用率
System.out.println("进程cpu使用率:"+getAttribute(mbsc,os,"ProcessCpuLoad"));//进程cpu使用率
System.out.println("============");//
//线程
ObjectNameThreading=newObjectName("java.lang:type=Threading");
System.out.println("活动线程:"+getAttribute(mbsc,Threading,"ThreadCount"));//活动线程
System.out.println("守护程序线程:"+getAttribute(mbsc,Threading,"DaemonThreadCount"));//守护程序线程
System.out.println("峰值:"+getAttribute(mbsc,Threading,"PeakThreadCount"));//峰值
System.out.println("启动的线程总数:"+getAttribute(mbsc,Threading,"TotalStartedThreadCount"));//启动的线程总数
ThreadMXBeanthreadBean2=ManagementFactory.newPlatformMXBeanProxy
(mbsc,ManagementFactory.THREAD_MXBEAN_NAME,ThreadMXBean.class);
System.out.println("活动线程:"+threadBean2.getThreadCount());//活动线程
ThreadMXBeanthreadBean3=ManagementFactory.getThreadMXBean();
System.out.println("本地活动线程:"+threadBean3.getThreadCount());//本地活动线程
System.out.println("============");//
ObjectNameCompilation=newObjectName("java.lang:type=Compilation");
System.out.println("总编译时间毫秒:"+getAttribute(mbsc,Compilation,"TotalCompilationTime"));//总编译时间毫秒
System.out.println("============");//
ObjectNameClassLoading=newObjectName("java.lang:type=ClassLoading");
System.out.println("已加载类总数:"+getAttribute(mbsc,ClassLoading,"TotalLoadedClassCount"));//已加载类总数
System.out.println("已加装当前类:"+getAttribute(mbsc,ClassLoading,"LoadedClassCount"));//已加装当前类
System.out.println("已卸载类总数:"+getAttribute(mbsc,ClassLoading,"UnloadedClassCount"));//已卸载类总数
System.out.println("==========================================================");//
//http://zookeeper.apache.org/doc/r3.4.6/zookeeperJMX.html
//org.apache.ZooKeeperService:name0=ReplicatedServer_id1,name1=replica.1,name2=Follower
ObjectNamereplica=newObjectName("org.apache.ZooKeeperService:name0=ReplicatedServer_id1,name1=replica.1");
System.out.println("replica.1运行状态:"+getAttribute(mbsc,replica,"State"));//运行状态
mbsc=createMBeanServer("192.168.1.100","9992","controlRole","123456");
System.out.println("==============节点树对象===========");
ObjectNamedataTreePattern=newObjectName("org.apache.ZooKeeperService:name0=ReplicatedServer_id?,name1=replica.?,name2=*,name3=InMemoryDataTree");
SetdataTreeSets=mbsc.queryNames(dataTreePattern,null);
IteratordataTreeIterator=dataTreeSets.iterator();
//只有一个
while(dataTreeIterator.hasNext()){
ObjectNamedataTreeObjectName=dataTreeIterator.next();
DataTreeMXBeandataTree=JMX.newMBeanProxy(mbsc,dataTreeObjectName,DataTreeMXBean.class);
System.out.println("节点总数:"+dataTree.getNodeCount());//节点总数
System.out.println("Watch总数:"+dataTree.getWatchCount());//Watch总数
System.out.println("临时节点总数:"+dataTree.countEphemerals());//Watch总数
System.out.println("节点名及字符总数:"+dataTree.approximateDataSize());//节点全路径和值的总字符数
MapdataTreeMap=dataTreeObjectName.getKeyPropertyList();
StringreplicaId=dataTreeMap.get("name1").replace("replica.","");
Stringrole=dataTreeMap.get("name2");//Follower,Leader,Observer,Standalone
StringcanonicalName=dataTreeObjectName.getCanonicalName();
introleEndIndex=canonicalName.indexOf(",name3");
ObjectNameroleObjectName=newObjectName(canonicalName.substring(0,roleEndIndex));
System.out.println("==============zk服务状态===========");
ZooKeeperServerMXBeanZooKeeperServer=JMX.newMBeanProxy(mbsc,roleObjectName,ZooKeeperServerMXBean.class);
System.out.println(role+"的IP和端口:"+ZooKeeperServer.getClientPort());//IP和端口
System.out.println(role+"活着的连接数:"+ZooKeeperServer.getNumAliveConnections());//连接数
System.out.println(role+"未完成请求数:"+ZooKeeperServer.getOutstandingRequests());//未完成的请求数
System.out.println(role+"接收的包:"+ZooKeeperServer.getPacketsReceived());//收到的包
System.out.println(role+"发送的包:"+ZooKeeperServer.getPacketsSent());//发送的包
System.out.println(role+"平均延迟(毫秒):"+ZooKeeperServer.getAvgRequestLatency());
System.out.println(role+"最大延迟(毫秒):"+ZooKeeperServer.getMaxRequestLatency());
System.out.println(role+"每个客户端IP允许的最大连接数:"+ZooKeeperServer.getMaxClientCnxnsPerHost());
System.out.println(role+"最大Session超时(毫秒):"+ZooKeeperServer.getMaxSessionTimeout());
System.out.println(role+"心跳时间(毫秒):"+ZooKeeperServer.getTickTime());
System.out.println(role+"版本:"+ZooKeeperServer.getVersion());//版本
//三个重置操作
//ZooKeeperServer.resetLatency();//重置min/avg/maxlatencystatistics
//ZooKeeperServer.resetMaxLatency();//重置最大延迟统计
//ZooKeeperServer.resetStatistics();//重置包和延迟所有统计
System.out.println("==============所有客户端的连接信息===========");
ObjectNameconnectionPattern=newObjectName("org.apache.ZooKeeperService:name0=ReplicatedServer_id?,name1=replica.?,name2=*,name3=Connections,*");
SetconnectionSets=mbsc.queryNames(connectionPattern,null);
ListconnectionList=newArrayList(connectionSets.size());
connectionList.addAll(connectionSets);
Collections.sort(connectionList);
for(ObjectNameconnectionON:connectionList){
System.out.println("=========================");
ConnectionMXBeanconnectionBean=JMX.newMBeanProxy(mbsc,connectionON,ConnectionMXBean.class);
System.out.println("IP+Port:"+connectionBean.getSourceIP());//
System.out.println("SessionId:"+connectionBean.getSessionId());//
System.out.println("PacketsReceived:"+connectionBean.getPacketsReceived());//收到的包
System.out.println("PacketsSent:"+connectionBean.getPacketsSent());//发送的包
System.out.println("MinLatency:"+connectionBean.getMinLatency());//
System.out.println("AvgLatency:"+connectionBean.getAvgLatency());//
System.out.println("MaxLatency:"+connectionBean.getMaxLatency());//
System.out.println("StartedTime:"+connectionBean.getStartedTime());//
System.out.println("EphemeralNodes:"+connectionBean.getEphemeralNodes().length);//
System.out.println("EphemeralNodes:"+Arrays.asList(connectionBean.getEphemeralNodes()));//
System.out.println("OutstandingRequests:"+connectionBean.getOutstandingRequests());//
//connectionBean.resetCounters();
//connectionBean.terminateConnection();
//connectionBean.terminateSession();
}
}
//closeconnection
if(connector!=null){
connector.close();
}
}
/**
*建立连接
*@paramip
*@paramjmxport
*@return
*/
publicstaticMBeanServerConnectioncreateMBeanServer(Stringip,
Stringjmxport,StringuserName,Stringpassword){
try{
StringjmxURL="service:jmx:rmi:///jndi/rmi://"+ip+":"
+jmxport+"/jmxrmi";
//jmxurl
JMXServiceURLserviceURL=newJMXServiceURL(jmxURL);
Mapmap=newHashMap();
String[]credentials=newString[]{userName,password};
map.put("jmx.remote.credentials",credentials);
connector=JMXConnectorFactory.connect(serviceURL,map);
MBeanServerConnectionmbsc=connector.getMBeanServerConnection();
returnmbsc;
}catch(IOExceptionioe){
ioe.printStackTrace();
System.err.println(ip+":"+jmxport+"连接建立失败");
}
returnnull;
}
/**
*使用MBeanServer获取对象名为[objName]的MBean的[objAttr]属性值
*
*静态代码:returnMBeanServer.getAttribute(ObjectNamename,Stringattribute)
*@parammbeanServer
*-MBeanServer实例
*@paramobjName
*-MBean的对象名
*@paramobjAttr
*-MBean的某个属性名
*@return属性值
*/
privatestaticStringgetAttribute(MBeanServerConnectionmbeanServer,
ObjectNameobjName,StringobjAttr){
if(mbeanServer==null||objName==null||objAttr==null)
thrownewIllegalArgumentException();
try{
returnString.valueOf(mbeanServer.getAttribute(objName,objAttr));
}catch(Exceptione){
returnnull;
}
}
}
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。如果你想了解更多相关内容请查看下面相关链接