使用JMX監(jiān)控Zookeeper狀態(tài)Java API
一、背景
上一篇通過(guò)Java自帶的JConsole來(lái)獲取zookeeper狀態(tài)。主要有幾個(gè)不方便的地方,zk集群一般會(huì)部署3或者5臺(tái),在多個(gè)JConsole窗口中切換比較麻煩,各個(gè)zk服務(wù)及歷史數(shù)據(jù)之間,不能直觀比較。一般會(huì)做一個(gè)WEB管理頁(yè)面來(lái)展示集群狀態(tài),設(shè)置報(bào)警閥值來(lái)做報(bào)警。
二、JVM平臺(tái)提供Mbeans
在Java5.0以上版本,有一組API可以讓Java應(yīng)用程序和允許的工具監(jiān)視和管理Java虛擬機(jī)(JVM)和虛擬機(jī)所在的本機(jī)操作系統(tǒng)。該組API在 java.lang.management
包。可以通過(guò)這些API可以監(jiān)控local端JVM,同時(shí)也可以監(jiān)控遠(yuǎn)端JVM。
通過(guò)靜態(tài)工廠方法獲取MXBean實(shí)例,從本地訪問(wèn)正在運(yùn)行的虛擬機(jī)的MXBean接口。這些Bean我們從ManagementFactory類中定義的靜態(tài)方法獲取;如ManagementFactory.getOperatingSystemMXBean();
其中不足就是只能獲取本地的JVM狀態(tài)。無(wú)法獲取遠(yuǎn)程的虛擬機(jī)數(shù)據(jù)。
- ClassLoadingMXBean Java虛擬機(jī)的類加載系統(tǒng)
- CompilationMXBean Java虛擬機(jī)的編譯系統(tǒng)
- MemoryMXBean Java虛擬機(jī)的內(nèi)存系統(tǒng)
- RuntimeMXBean Java虛擬機(jī)的運(yùn)行時(shí)系統(tǒng)
- OperatingSystemMXBean Java虛擬機(jī)在其上運(yùn)行的操作系統(tǒng)
- GarbageCollectorMXBean Java虛擬機(jī)中的垃圾回收器
- MemoryManagerMXBean Java虛擬機(jī)中的內(nèi)存管理器
- MemoryPoolMXBean Java虛擬機(jī)中的內(nèi)存池
三、Zookeeper提供出來(lái)的Mbeans
構(gòu)造MXBean代理實(shí)例,通過(guò)代理將方法調(diào)用轉(zhuǎn)發(fā)到給定的MBeanServe。JConsole能夠監(jiān)控的項(xiàng)目,通過(guò)API都能獲取到。
具體代碼如下:
import java.io.IOException; import java.lang.management.ClassLoadingMXBean; import java.lang.management.CompilationMXBean; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.lang.management.ThreadMXBean; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.management.InstanceNotFoundException; import javax.management.IntrospectionException; import javax.management.JMX; import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.management.ReflectionException; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import org.apache.zookeeper.server.ConnectionMXBean; import org.apache.zookeeper.server.DataTreeMXBean; import org.apache.zookeeper.server.ZooKeeperServerMXBean; public class ZkJMXTest { static JMXConnector connector; /** * @param args * @throws IOException * @throws MalformedObjectNameException * @throws InstanceNotFoundException * @throws ReflectionException * @throws IntrospectionException */ public static void main(String[] args) throws IOException, MalformedObjectNameException, InstanceNotFoundException, IntrospectionException, ReflectionException { OperatingSystemMXBean osbean = ManagementFactory.getOperatingSystemMXBean(); System.out.println("體系結(jié)構(gòu):" + osbean.getArch());//操作系統(tǒng)體系結(jié)構(gòu) System.out.println("處理器核數(shù):" + osbean.getAvailableProcessors());///核數(shù) System.out.println("名字:" + osbean.getName());//名字 System.out.println(osbean.getVersion());//操作系統(tǒng)版本 ThreadMXBean threadBean=ManagementFactory.getThreadMXBean(); System.out.println("活動(dòng)線程:" + threadBean.getThreadCount());//總線程數(shù) ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean(); CompilationMXBean compilationMXBean = ManagementFactory.getCompilationMXBean(); System.out.println("==========="); // 通過(guò) MBeanServer間接地訪問(wèn) MXBean 接口 MBeanServerConnection mbsc = createMBeanServer("192.168.1.100", "9991", "controlRole", "123456"); // 操作系統(tǒng) ObjectName os = new ObjectName("java.lang:type=OperatingSystem"); System.out.println("體系結(jié)構(gòu):" + getAttribute(mbsc, os, "Arch"));//體系結(jié)構(gòu) System.out.println("處理器核數(shù):" + getAttribute(mbsc, os, "AvailableProcessors"));//核數(shù) System.out.println("總物理內(nèi)存:" + getAttribute(mbsc, os, "TotalPhysicalMemorySize"));//總物理內(nèi)存 System.out.println("空閑物理內(nèi)存:" + getAttribute(mbsc, os, "FreePhysicalMemorySize"));//空閑物理內(nèi)存 System.out.println("總交換空間:" + getAttribute(mbsc, os, "TotalSwapSpaceSize"));//總交換空間 System.out.println("空閑交換空間:" + getAttribute(mbsc, os, "FreeSwapSpaceSize"));//空閑交換空間 System.out.println("操作系統(tǒng):" + getAttribute(mbsc, os, "Name")+ getAttribute(mbsc, os, "Version"));//操作系統(tǒng) System.out.println("提交的虛擬內(nèi)存:" + getAttribute(mbsc, os, "CommittedVirtualMemorySize"));//提交的虛擬內(nèi)存 System.out.println("系統(tǒng)cpu使用率:" + getAttribute(mbsc, os, "SystemCpuLoad"));//系統(tǒng)cpu使用率 System.out.println("進(jìn)程cpu使用率:" + getAttribute(mbsc, os, "ProcessCpuLoad"));//進(jìn)程cpu使用率 System.out.println("============");// // 線程 ObjectName Threading = new ObjectName("java.lang:type=Threading"); System.out.println("活動(dòng)線程:" + getAttribute(mbsc, Threading, "ThreadCount"));// 活動(dòng)線程 System.out.println("守護(hù)程序線程:" + getAttribute(mbsc, Threading, "DaemonThreadCount"));// 守護(hù)程序線程 System.out.println("峰值:" + getAttribute(mbsc, Threading, "PeakThreadCount"));// 峰值 System.out.println("啟動(dòng)的線程總數(shù):" + getAttribute(mbsc, Threading, "TotalStartedThreadCount"));// 啟動(dòng)的線程總數(shù) ThreadMXBean threadBean2 = ManagementFactory.newPlatformMXBeanProxy (mbsc, ManagementFactory.THREAD_MXBEAN_NAME, ThreadMXBean.class); System.out.println("活動(dòng)線程:" + threadBean2.getThreadCount());// 活動(dòng)線程 ThreadMXBean threadBean3 = ManagementFactory.getThreadMXBean(); System.out.println("本地活動(dòng)線程:" + threadBean3.getThreadCount());// 本地活動(dòng)線程 System.out.println("============");// ObjectName Compilation = new ObjectName("java.lang:type=Compilation"); System.out.println("總編譯時(shí)間 毫秒:" + getAttribute(mbsc, Compilation, "TotalCompilationTime"));// 總編譯時(shí)間 毫秒 System.out.println("============");// ObjectName ClassLoading = new ObjectName("java.lang:type=ClassLoading"); System.out.println("已加載類總數(shù):" + getAttribute(mbsc, ClassLoading, "TotalLoadedClassCount"));// 已加載類總數(shù) System.out.println("已加裝當(dāng)前類:" + getAttribute(mbsc, ClassLoading, "LoadedClassCount"));// 已加裝當(dāng)前類 System.out.println("已卸載類總數(shù):" + getAttribute(mbsc, ClassLoading, "UnloadedClassCount"));// 已卸載類總數(shù) System.out.println("==========================================================");// // http://zookeeper.apache.org/doc/r3.4.6/zookeeperJMX.html // org.apache.ZooKeeperService:name0=ReplicatedServer_id1,name1=replica.1,name2=Follower ObjectName replica = new ObjectName("org.apache.ZooKeeperService:name0=ReplicatedServer_id1,name1=replica.1"); System.out.println("replica.1運(yùn)行狀態(tài):" + getAttribute(mbsc, replica, "State"));// 運(yùn)行狀態(tài) mbsc = createMBeanServer("192.168.1.100", "9992", "controlRole", "123456"); System.out.println("==============節(jié)點(diǎn)樹(shù)對(duì)象==========="); ObjectName dataTreePattern = new ObjectName("org.apache.ZooKeeperService:name0=ReplicatedServer_id?,name1=replica.?,name2=*,name3=InMemoryDataTree"); Set<ObjectName> dataTreeSets = mbsc.queryNames(dataTreePattern, null); Iterator<ObjectName> dataTreeIterator = dataTreeSets.iterator(); // 只有一個(gè) while (dataTreeIterator.hasNext()) { ObjectName dataTreeObjectName = dataTreeIterator.next(); DataTreeMXBean dataTree = JMX.newMBeanProxy(mbsc, dataTreeObjectName, DataTreeMXBean.class); System.out.println("節(jié)點(diǎn)總數(shù):" + dataTree.getNodeCount());// 節(jié)點(diǎn)總數(shù) System.out.println("Watch總數(shù):" + dataTree.getWatchCount());// Watch總數(shù) System.out.println("臨時(shí)節(jié)點(diǎn)總數(shù):" + dataTree.countEphemerals());// Watch總數(shù) System.out.println("節(jié)點(diǎn)名及字符總數(shù):" + dataTree.approximateDataSize());// 節(jié)點(diǎn)全路徑和值的總字符數(shù) Map<String, String> dataTreeMap = dataTreeObjectName.getKeyPropertyList(); String replicaId = dataTreeMap.get("name1").replace("replica.", ""); String role = dataTreeMap.get("name2");// Follower,Leader,Observer,Standalone String canonicalName = dataTreeObjectName.getCanonicalName(); int roleEndIndex = canonicalName.indexOf(",name3"); ObjectName roleObjectName = new ObjectName(canonicalName.substring(0, roleEndIndex)); System.out.println("==============zk服務(wù)狀態(tài)==========="); ZooKeeperServerMXBean ZooKeeperServer = JMX.newMBeanProxy(mbsc, roleObjectName, ZooKeeperServerMXBean.class); System.out.println(role + " 的IP和端口:" + ZooKeeperServer.getClientPort());// IP和端口 System.out.println(role + " 活著的連接數(shù):" + ZooKeeperServer.getNumAliveConnections());// 連接數(shù) System.out.println(role + " 未完成請(qǐng)求數(shù):" + ZooKeeperServer.getOutstandingRequests());// 未完成的請(qǐng)求數(shù) System.out.println(role + " 接收的包:" + ZooKeeperServer.getPacketsReceived());// 收到的包 System.out.println(role + " 發(fā)送的包:" + ZooKeeperServer.getPacketsSent());// 發(fā)送的包 System.out.println(role + " 平均延遲(毫秒):" + ZooKeeperServer.getAvgRequestLatency()); System.out.println(role + " 最大延遲(毫秒):" + ZooKeeperServer.getMaxRequestLatency()); System.out.println(role + " 每個(gè)客戶端IP允許的最大連接數(shù):" + ZooKeeperServer.getMaxClientCnxnsPerHost()); System.out.println(role + " 最大Session超時(shí)(毫秒):" + ZooKeeperServer.getMaxSessionTimeout()); System.out.println(role + " 心跳時(shí)間(毫秒):" + ZooKeeperServer.getTickTime()); System.out.println(role + " 版本:" + ZooKeeperServer.getVersion());// 版本 // 三個(gè)重置操作 // ZooKeeperServer.resetLatency(); //重置min/avg/max latency statistics // ZooKeeperServer.resetMaxLatency(); //重置最大延遲統(tǒng)計(jì) // ZooKeeperServer.resetStatistics(); // 重置包和延遲所有統(tǒng)計(jì) System.out.println("==============所有客戶端的連接信息==========="); ObjectName connectionPattern = new ObjectName("org.apache.ZooKeeperService:name0=ReplicatedServer_id?,name1=replica.?,name2=*,name3=Connections,*"); Set<ObjectName> connectionSets = mbsc.queryNames(connectionPattern, null); List<ObjectName> connectionList = new ArrayList<ObjectName>(connectionSets.size()); connectionList.addAll(connectionSets); Collections.sort(connectionList); for (ObjectName connectionON : connectionList) { System.out.println("========================="); ConnectionMXBean connectionBean = 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());// 發(fā)送的包 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(); } } // close connection if (connector != null) { connector.close(); } } /** * 建立連接 * @param ip * @param jmxport * @return */ public static MBeanServerConnection createMBeanServer(String ip, String jmxport, String userName, String password) { try { String jmxURL = "service:jmx:rmi:///jndi/rmi://" + ip + ":" + jmxport + "/jmxrmi"; // jmxurl JMXServiceURL serviceURL = new JMXServiceURL(jmxURL); Map<String, String[]> map = new HashMap<String, String[]>(); String[] credentials = new String[] { userName, password }; map.put("jmx.remote.credentials", credentials); connector = JMXConnectorFactory.connect(serviceURL, map); MBeanServerConnection mbsc = connector.getMBeanServerConnection(); return mbsc; } catch (IOException ioe) { ioe.printStackTrace(); System.err.println(ip + ":" + jmxport + " 連接建立失敗"); } return null; } /** * 使用MBeanServer獲取對(duì)象名為[objName]的MBean的[objAttr]屬性值 * <p> * 靜態(tài)代碼: return MBeanServer.getAttribute(ObjectName name, String attribute) * @param mbeanServer * - MBeanServer實(shí)例 * @param objName * - MBean的對(duì)象名 * @param objAttr * - MBean的某個(gè)屬性名 * @return 屬性值 */ private static String getAttribute(MBeanServerConnection mbeanServer, ObjectName objName, String objAttr) { if (mbeanServer == null || objName == null || objAttr == null) throw new IllegalArgumentException(); try { return String.valueOf(mbeanServer.getAttribute(objName, objAttr)); } catch (Exception e) { return null; } } }
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
相關(guān)文章
SpringBoot集成redis與session實(shí)現(xiàn)分布式單點(diǎn)登錄
這篇文章主要介紹了SpringBoot集成redis與session實(shí)現(xiàn)分布式單點(diǎn)登錄,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09mybatis plus saveBatch方法方法執(zhí)行慢導(dǎo)致接口發(fā)送慢解決分析
這篇文章主要為大家介紹了mybatis plus saveBatch方法導(dǎo)致接口發(fā)送慢解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10在IntelliJ IDEA中多線程并發(fā)代碼的調(diào)試方法詳解
這篇文章主要介紹了在IntelliJ IDEA中多線程并發(fā)代碼的調(diào)試方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08Springboot的spring-boot-maven-plugin導(dǎo)入失敗的解決方案
這篇文章主要介紹了Springboot的spring-boot-maven-plugin導(dǎo)入失敗的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07IDEA集成JProfiler11可視化工具的詳細(xì)流程(安裝、集成、測(cè)試)
小編打算在IDEA中集成一下JProfiler11(現(xiàn)在有12版本了)工具,到網(wǎng)上搜都沒(méi)有找到合適的,于是自己動(dòng)手寫個(gè),關(guān)于IDEA集成JProfiler11可視化工具(安裝、集成、測(cè)試)相關(guān)知識(shí)感興趣的朋友一起看看吧2021-06-06Java實(shí)現(xiàn)自定義語(yǔ)言和表達(dá)式解析的解釋器模式
Java解釋器設(shè)計(jì)模式通過(guò)解析自定義語(yǔ)言和表達(dá)式,實(shí)現(xiàn)對(duì)復(fù)雜邏輯的處理,提高程序可擴(kuò)展性和靈活性。它將語(yǔ)法解析和執(zhí)行過(guò)程分離,通過(guò)抽象語(yǔ)法樹(shù)和解釋器實(shí)現(xiàn)對(duì)語(yǔ)言和表達(dá)式的解析和求值,避免了硬編碼和復(fù)雜的條件判斷,提高了程序的可讀性和可維護(hù)性2023-04-04Mybatis中實(shí)體類屬性與數(shù)據(jù)列表間映射方法介紹
這篇文章主要介紹了Mybatis中實(shí)體類屬性與數(shù)據(jù)列表間映射方法介紹,一共四中方法,供大家參考。2017-10-10Intellij 下 mybatis 插件 MyBatisCodeHelperPro破解步驟詳解
這篇文章主要介紹了Intellij 下 mybatis 插件 MyBatisCodeHelperPro破解步驟,本文分步驟給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Spring事務(wù)隔離級(jí)別簡(jiǎn)介及實(shí)例解析
這篇文章主要介紹了Spring事務(wù)隔離級(jí)別簡(jiǎn)介及實(shí)例解析,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-02-02