• 如何使用JMX来管理程序?


    什么是JMX

    JMX,全称Java Management Extensions,用于我们管理和监控java应用程序。JMX有以下用途:

    1. 监控应用程序的运行状态和相关统计信息。
    2. 修改应用程序的配置(无需重启)。
    3. 状态变化或出错时通知处理。

    举个例子,我们可以通过jconsole监控应用程序的堆内存使用量、线程数、类数,查看某些配置信息,甚至可以动态地修改配置。另外,有时还可以利用JMX来进行测试。

    本文将介绍以下内容:

    1. 什么是JMX
    2. JMX的基础架构;
    3. 如何使用JMX

    JMX的基础架构

    首先,看下这种图:

    JMX的基础架构

    这里简单介绍下这三层结构:

    层次 描述
    Instrumentation 主要包括了一系列的接口定义和描述如何开发MBean的规范。在JMXMBean代表一个被管理的资源实例,通过MBean中暴露的方法和属性,外界可以获取被管理的资源的状态和操纵MBean的行为
    Agent 用来管理相应的资源,并且为远端用户提供访问的接口。该层的核心是MBeanServer,所有的MBean都要向它注册,才能被管理。注册在MBeanServer上的MBean并不直接和远程应用程序进行通信,他们通过协议适配器(Adapter)和连接器(Connector)进行通信。
    Distributed 定义了一系列用来访问Agent的接口和组件,包括AdapterConnector的描述。注意,AdapterConnector的区别在于:Adapter是使用某种Internet协议来与 Agent获得联系,Agent端会有一个对象 (Adapter)来处理有关协议的细节。比如SNMP AdapterHTTP Adapter。而Connector则是使用类似RPC的方式来访问Agent,在Agent端和客户端都必须有这样一个对象来处理相应的请求与应答。比如RMI Connector

    怎么使用JMX

    需求

    1. 测试本地连接管理MBean
    2. 测试远程连接管理MBean,包括代码实现、启动参数、启动参数+配置文件等方式。
    3. 如何开启账号密码认证。

    工程环境

    JDK:1.8.0_231

    maven:3.6.1

    IDE:eclipse 4.12

    主要步骤

    1. 定义MBean接口,并编写实现类;
    2. 注册MBeanMBeanServe
    3. 启动程序;
    4. 使用jconsole连接管理该程序。

    创建项目

    项目类型Maven Project,打包方式jar

    引入依赖

    入门案例暂时不需要引入外部依赖。

    编写MBean接口

    注意,接口名格式必须为:被管理的类的类名+MBean

    public interface UserMBean {
    
    	String getName();
    
    	void setName(String name);
    
    	Integer getAge();
    
    	void setAge(Integer age);
    
    	String getAddress();
    
    	void setAddress(String address);
    	
    	String sayHello();
    	
    }
    

    编写实现类

    这里简单实现下就行。当属性被设置时,会在控制台打印相关内容。

    public class User implements UserMBean {
    
    	private String name;
    
    	private Integer age;
    
    	private String address;
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		System.err.println("set name to " + name);
    		this.name = name;
    	}
    
    	public Integer getAge() {
    		return age;
    	}
    
    	public void setAge(Integer age) {
    		System.err.println("set age to " + age);
    		this.age = age;
    	}
    
    	public String getAddress() {
    		return address;
    	}
    
    	public void setAddress(String address) {
    		System.err.println("set address to " + address);
    		this.address = address;
    	}
    
    	public String sayHello() {
    		return "Hello!";
    	}
    
    }
    

    本地连接

    注册MBean

    路径为test目录下的cn.zzs.jmx,类名JMXTest。只有将MBean注册到MBeanServerMBean才能被管理。MBean的对象名格式为:域名:type=MBean类型,name=MBean名称。其中,域名MBean名称可以随便取,对象名中除了type,我们还可以自定义其他条目,以方便管理。

    注意,为了让这个程序持续工作,这里强制线程睡眠。

    	public static void main(String[] args) throws Exception {
    		// 设置MBean对象名,格式为:“域名:type=MBean类型,name=MBean名称”
    		String jmxName = "cn.zzs.jmx:type=user,name=user001";
    		// 获得MBeanServer
    		MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    		// 创建ObjectName
    		ObjectName objectName = new ObjectName(jmxName);
    		// 创建并注册MBean
    		server.registerMBean(new User(), objectName);
    		Thread.sleep(60 * 60 * 1000);
    	}
    

    测试

    启动程序,打开jconsole(在JDK安装路径的bin目录下),出现如下界面,这时可以看到我们测试的程序:

    jconsole_01.png

    选择JMXTest后,点击连接,这时如果弹窗“安全连接失败,是否以不安全的方式重试”,这是因为我们没有开启ssl加密,可以不去理会它。点击不安全的连接,即可进入以下页面:

    jconsole_02.png

    通过这个窗口我们可以查看程序的堆内存使用量、线程、类等信息,我们再点击MBean选项卡,可以看到我们编写的MBean,我们定义的对象名为cn.zzs.jmx:type=user,name=user001,其中cn.zzs.jmx作为第一级目录,type=user作为第二级目录,name=user001对应具体的对象,它具备属性和操作。其中,usersettergetter方法被合并在了一起。

    jconsole_03.png

    通过这个界面,我们可以查看和设置user的属性,或调用它的方法。例如,我先设置name的值,通过程序控制台可以看到该方法被调用了:

    jconsole_04.png

    接着我再调用sayHello方法:

    jconsole_05.png

    通过以上例子,可以看到,JMX还是非常有用的,除了查看类的属性外,我们还可以在不重启程序的情况下进行配置或执行某些方法。

    以上例子中,我们只能在本地访问JMXTest,接下来介绍如何实现远程连接。本文介绍三种方式,可根据实际场景选择:

    1. 代码实现;
    2. 启动参数配置;
    3. 启动参数+文件配置。

    远程连接方式一(代码实现)

    本例子在本地连接的基础上修改。

    开启远程连接

    注意,这里的localhost最好改为你的IP,不然可能连接不上。

    	public static void main(String[] args) throws Exception {
    		// 设置MBean对象名,格式为:“域名:type=MBean类型,name=MBean名称”
    		String jmxName = "cn.zzs.jmx:type=user,name=user001";
    		// 获得MBeanServer
    		MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    		// 创建ObjectName
    		ObjectName objectName = new ObjectName(jmxName);
    		// 创建并注册MBean
    		server.registerMBean(new User(), objectName);
    		// 注册一个端口
    		LocateRegistry.createRegistry(9999);
    		// URL路径的结尾可以随意指定,但如果需要用Jconsole来进行连接,则必须使用jmxrmi
    		JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");
    		JMXConnectorServer jcs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server);
    		jcs.start();
    	}
    

    测试

    打开jconsole,使用远程连接方式,输入我们设置好的ip和端口,点击连接即可:

    jconsole_06.png

    远程连接方式二(启动参数)

    本例子在本地连接的基础上修改。在程序启动时加入以下启动参数,也可以实现远程连接:

    -Djava.rmi.server.hostname=<your-ip> // 你的ip
    -Dcom.sun.management.jmxremote.port=9999 // 开放端口号
    -Dcom.sun.management.jmxremote.local.only=false // 是否只能本地连接
    -Dcom.sun.management.jmxremote.ssl=false // 是否使用ssl加密
    -Dcom.sun.management.jmxremote.authenticate=false // 是否需要账号密码认证
    

    可以看到,我们关闭了ssl加密和账号密码认证。

    远程连接方式三(启动参数+配置文件)

    本例子在本地连接的基础上修改。

    启动参数

    在程序启动时加入以下启动参数,并结合配置文件,也可以实现远程连接:

    -Dcom.sun.management.config.file=D:/growUp/git_repository/jdk-extend/02-jmx-demo/src/main/resources/config/management.properties // 配置文件路径
    -Djava.rmi.server.hostname=<your-ip>
    

    配置文件

    在配置文件中配置以下参数:

    # 开放端口号
    com.sun.management.jmxremote.port=9999
    # 是否只能本地连接
    com.sun.management.jmxremote.local.only=false
    # 是否使用ssl加密
    com.sun.management.jmxremote.ssl=false
    # 是否需要账号密码认证
    com.sun.management.jmxremote.authenticate=false
    

    关于management.propertie的详细配置,可以在$JRE/lib/management/目录下找到。其实,当我们在启动参数中存在以下参数时,默认会去读取$JRE/lib/management/management.properties的配置文件。

    #    -Dcom.sun.management.jmxremote.port=<port-number>
    # or -Dcom.sun.management.snmp.port=<port-number>
    

    设置账户密码

    实际使用中,我们更希望采用安全加密的方式来监控程序,这个时候我们可以设置ssl加密或账号密码认证。ssl加密的本文暂时不扩展,这里只介绍如何设置账号密码认证。

    启动参数

    和上个例子一样,需要设置如下启动参数:

    -Dcom.sun.management.config.file=D:/growUp/git_repository/jdk-extend/02-jmx-demo/src/main/resources/config/management.properties
    -Djava.rmi.server.hostname=<your-ip>
    

    配置文件

    配置文件中加入以下内容:

    # 开放端口号
    com.sun.management.jmxremote.port=9999
    # 是否只能本地连接
    com.sun.management.jmxremote.local.only=false
    # 是否使用ssl加密
    com.sun.management.jmxremote.ssl=false
    # 是否需要账号密码认证
    com.sun.management.jmxremote.authenticate=true
    # 密码文件路径
    com.sun.management.jmxremote.password.file=D:/growUp/git_repository/jdk-extend/02-jmx-demo/src/main/resources/config/jmxremote.password
    # 权限文件路径
    com.sun.management.jmxremote.access.file=D:/growUp/git_repository/jdk-extend/02-jmx-demo/src/main/resources/config/jmxremote.access
    

    在此之前,我们需要配置好密码文件和权限文件:

    密码文件

    ZhangZiSheng001 root
    

    权限文件

    ZhangZiSheng001 readwrite
    

    测试

    打开jconsole,选择远程连接,并输入账号密码,点击连接即可:

    jconsole_07.png

    参考资料

    相关源码请移步:https://github.com/ZhangZiSheng001/02-jmx-demo

    本文为原创文章,转载请附上原文出处链接:https://www.cnblogs.com/ZhangZiSheng001/p/12128915.html

  • 相关阅读:
    企业财务分析四步走
    切比雪夫不等式
    归并排序
    sql笔记
    paper 150:GCC--GNU Compiler Collection(GNU编译器套件)
    paper 149:Deep Learning 学习笔记(一)
    paper 148: Face Databases
    paper 147:Deep Learning -- Face Data Augmentation(一)
    paper 146:CAFFE--leveldb/lmdb文件
    paper 145:caffe-深度学习框架的搭建
  • 原文地址:https://www.cnblogs.com/ZhangZiSheng001/p/12128915.html
Copyright © 2020-2023  润新知