当前位置: 首页 > article >正文

Java中的JMX的使用

文章目录

        • 1. 定义和存在的意义
        • 2. 架构
          • 2.1 Instrumentation
          • 2.2 JMX Agent
          • 2.3 Remote Management
        • 3. 启动和连接
          • 3.1 注册MBean
          • 3.2 有两个方式启动JMX Agent
          • 3.3 Remote Management(客户端)
        • 4. MBeanServerConnection使用
          • 4.1 列出所有的MBean
          • 4.2 列出所有的Domain
          • 4.3 MBean计数
          • 4.4 获取和设置属性
          • 4.5 调用方法
          • 4.6 获取MBeanInfo

1. 定义和存在的意义

JMX是Java Management Extention的缩写,本质的出发点是让外部能获取、设置应用的信息及操作。如果是Web应用可以通过HTTP接口暴露,如果RPC应用可以通过RPC调用暴露,但是不通用。JMX就是为这类管理接口提供一个统一的访问方式。

2. 架构

JMX在架构上分为3层:

  • Instrumentation
  • JMX agent
  • Remote management
2.1 Instrumentation

Instrumentation提供了MBean创建的规范,JDK自带了一组叫做MXBean的特殊MBean,对外暴露了一些JVM信息及操作。

2.2 JMX Agent

JMX Agent用来管理Instrument, JMX Agent的核心是MBeanServer(用来注册MBean),并至少提供一组adaptor和connector(可以理解为通信协议和通信方式,允许外部程序或者客户端和JMX Agent通信)

2.3 Remote Management

可以理解为JMX Agent的客户端,通过不同的adapter和connect(协议和通信方式)连接到JMX Agent。

3. 启动和连接
3.1 注册MBean
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
String domain = "MyMBean";
// 注册hello
ObjectName helloName = new ObjectName(domain + ":name=hello");
server.registerMBean(new Hello(),helloName);
3.2 有两个方式启动JMX Agent
  • 使用JVM参数
-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=1099 
-Dcom.sun.management.jmxremote.local.only=false 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false
  • 使用Java代码
String domain = "jmxrmi"
int rmiPort = 1099;
Registry registry = LocateRegistry.createRegistry(rmiPort);
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + rmiPort + "/" + domain);
JMXConnectorServer jmxConnector = JMXConnectorServerFactory.newJMXConnectorServer(url,null,server);
jmxConnector.start();

如果是代码或者是远程连接JMX Agent,后续会用到JMXServiceURL的地址。和使用Java代码创建不同,JVM参数的domain值固定为jmxrmi

3.3 Remote Management(客户端)

客户端的方式也有很多,这里介绍两种

  • JConsole 有两种选项,本地进程,可以选择进程ID连接,远程进程要使用JMXServiceURL里的地址

    在这里插入图片描述

  • Java代码

String domain = "jmxrmi";
int rmiPort = 1099;
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + rmiPort + "/" + domain);
JMXConnector jmxc = JMXConnectorFactory.connect(url);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
4. MBeanServerConnection使用
4.1 列出所有的MBean
Set<ObjectInstance> ins = mbsc.queryMBeans(null,null);
for(ObjectInstance i : ins) {
    System.out.println("object: " + i.getObjectName());
}
4.2 列出所有的Domain
String[] domains = mbsc.getDomains();
for (String d : domains) {
    System.out.println(d);
}
4.3 MBean计数
System.out.println("MBeanCount:" + mbsc.getMBeanCount());
4.4 获取和设置属性
String domain = "MyMBean";
ObjectName helloName = new ObjectName(domain + ":name=hello");
System.out.println("getAttribute:--->" + mbsc.getAttribute(helloName, "Slogan")); // 获取
mbsc.setAttribute(helloName, new Attribute("Slogan", "" + System.nanoTime())); // 设置
System.out.println("getAttribute after modified--->" + mbsc.getAttribute(helloName, "Slogan")); // 获取
4.5 调用方法

有两种方式

  • 使用MBeanServerConnection
String domain = "MyMBean";
ObjectName helloName = new ObjectName(domain + ":name=hello");

mbsc.invoke(helloName, "printHello", new String[]{"shit"}, new String[]{String.class.getName()}); // 没有返回值
Object resp = mbsc.invoke(helloName, "daydream", new Integer[]{5000}, new String[]{Integer.class.getName()}); // 返回值
System.out.println("daydream:--->" + resp);
  • 使用MBeanServerInvocationHandler生成代理类
String domain = "MyMBean";
ObjectName helloName = new ObjectName(domain + ":name=hello");

HelloMBean proxy = MBeanServerInvocationHandler.newProxyInstance(mbsc,helloName,HelloMBean.class,false);
System.out.println("proxy get attribute:" + proxy.getSlogan());
System.out.println("proxy invoke:" + proxy.daydream(9999));
4.6 获取MBeanInfo
String domain = "MyMBean";
ObjectName helloName = new ObjectName(domain + ":name=hello");

MBeanInfo beanInfo = mbsc.getMBeanInfo(helloName);
System.out.println("class name:" + beanInfo.getClassName()); // MBean实现类

MBeanAttributeInfo[] attrinfos = beanInfo.getAttributes();  // MBean的属性
for(MBeanAttributeInfo a: attrinfos) {
    System.out.println("attribute name:" + a.getName());
}

MBeanOperationInfo[] operationInfos = beanInfo.getOperations(); // MBean上的操作
for(MBeanOperationInfo o: operationInfos) {
    System.out.println("operation name:" + o.getName());
}

http://www.kler.cn/a/151956.html

相关文章:

  • 常用的设计模式
  • 【docker系列】docker实战之部署SpringBoot项目
  • 互联网计算机 IC 生态发展大揭秘,DFINITY 官方扶持计划全公开!
  • 【驱动】SPI驱动分析(三)-SPI关键数据类型
  • C语言--不创建第三个变量,实现对两个数字的交换
  • springboot使用定时任务
  • 不是默认进入Linux|总是自动进入windows系统
  • conda环境下,安装所有包都报错:No module named ‘certifi‘
  • ICC2:使用analyze_lib_cell_placement检查lib cell的pass rate
  • 游戏开发团队配置与协作流程
  • 智能优化算法应用:基于旗鱼算法无线传感器网络(WSN)覆盖优化 - 附代码
  • Linux设置Nginx开机自启
  • JS:获取当前日期是本年度的第几周
  • 如何在3dMax中实现创建对象时自动指定材质?
  • Sealos 云操作系统私有化部署教程
  • 开闭原则:提高扩展性的小技巧
  • shared_ptr子类指针转换成父类指针
  • 主流数据库类型总结
  • 【Web】攻防世界Web_php_wrong_nginx_config
  • Windows Terminal CMD 终端配置方案: 不只是酷炫外观