zoukankan      html  css  js  c++  java
  • JMX jconsole 的使用

    JMX

    1. JMX简单介绍

     JMX的全称为Java Management Extensions. 顾名思义,是管理Java的一种扩展。这种机制可以方便的管理正在运行中的Java程序。常用于管理线程,内存,日志Level,服务重启,系统环境等。

    JConsole和JVisualVM中能够监控到JAVA应用程序和JVM的相关信息都是通过JMX实现的。

    先粘一段内容  

      1、程序初哥一般是写死在程序中,到要改变的时候就去修改代码,然后重新编译发布。
    
      2、程序熟手则配置在文件中(JAVA一般都是properties文件),到要改变的时候只要修改配置文件,但还是必须重启系统,以便读取配置文件里最新的值。
      
      3、程序好手则会写一段代码,把配置值缓存起来,系统在获取的时候,先看看配置文件有没有改动,如有改动则重新从配置里读取,否则从缓存里读取。
    
      4、程序高手则懂得物为我所用,用JMX把需要配置的属性集中在一个类中,然后写一个MBean,再进行相关配置。另外JMX还提供了一个工具页,以方便我们对参数值进行修改。

     

    2、JMX架构介绍

    基础监测层

      监控层的作用就是使用MBean来监控我们关心的性能指标。因为我们通常关注的性能指标比较多,通常情况下,在监控层我们会有多个MBean,每个MBean监控一类信息。

    JMX代理

      JMX代理是内嵌在Java应用程序中的,JMX代理相当于一个容器,所有的MBean都注册到这个容器中,这个容器可以接受外部的请求,返回MBean的监控信息。JMX Agent的核心组件是MBean server,它是一个管理对象的服务器,MBeans在其中注册。一个JMX代理还包括一组用于管理MBeans的服务和至少一个通信适配器(adaptor)或连接器(connector) 以供管理程序访问  

    远程管理层

      JMX 可以以多重方式来访问JMX技术监测信息,既可以通过现有的管理协议,比如简单网络管理协议(SNMP),也可以通过专利性的协议。MBean server依赖协议适配器(adaptors)和连接器(connectors)来让JMX代理供管理程序(位于JMX代理所在的JVM之外)访问。
      每个适配器都通过一个特定的协议提供一个包含了所有注册在MBean Server中的MBeans的视图。比如,一个HTML适配器可以在一个浏览器中显示一个MBean。

    3、MBean与MXBean的介绍

    MBean介绍

     MBean也是JavaBean的一种,在JMX中代表一种可以被管理的资源。一个MBean接口由属性(可读的,可能也是可写的)和操作(可以由应用程序调用)组成。MBean可分为如下四种:

     类型                                                 描述

    standard MBean         这种类型的MBean最简单,一个标准的MBean由一个MBean接口(该MBean接口列出了所有被暴露的属性和操作对应的方法)

                    和一个class(这 个class实现了这个MBean接口并提供被监测资源的功能)组成(接口和class必须放在同一个包下,不然会出错)。

                    它的命名也必须遵循一定的规范,例如我们的MBean为Hello,则接口必须为HelloMBean。标准MBean只能操作基本数据类型,

                    如 int、dubbo、lang等。                

    dynamic MBean         必须实现javax.management.DynamicMBean接口,所有的属性,方法都在运行时定义 

    open MBean          此MBean的规范还不完善,正在改进中

    model MBean          与标准和动态MBean相比,你可以不用写MBean类,只需使用javax.management.modelmbean.RequiredModelMBean即可。

                     RequiredModelMBean实现了ModelMBean接口,而ModelMBean扩展了DynamicMBean接口,因此与DynamicMBean相似,
                     Model MBean的管理资源也是在运行时定义的。与DynamicMBean不同的是,DynamicMBean管理的资源一般定义
                     在DynamicMBean中(运行时才决定管理那些资源),而model MBean管理的资源并不在MBean中,而是在外部(通常是一个类),
                     只有在运行时,才通过set方法将其加入到model MBean中。后面的例子会有详细介绍

    MXBean
      MXBean是MBean的一种,MXBean与MBean一样都需要定义一个接口和class类,但是MXBean并不要求Java类的名称必须与接口名称前部分相同。另外MXBean中还可以正常使用自定义数据类型;
      如果在MBean中使用自定义数据类型的话,通过JConsole查看时会显示不可用。 当MXBean中使用被转换成CompositeDataSupport类

    标准MBean与MXBean的区别
      1、在标准MBean中使用自定义数据类型时,JConsole中会显示不可用;而在MXBean中可以正常所使用。
      2、标准的MBean接口与Class的命名必须遵守是一定规范,而MXBean的接口与Class的命名没有约束条件。

    4. JMX的使用

    标准MBean 使用规范

      标准的MBean由一个MBean接口和一个Class类组成,并且接口必须命名为 xxxMBean 而 Class类名必须为 xxx 放与同一个包下,若不在同一包下运行时将出异常。

    JMX的使用步骤
      1. 定义接口与资源实体类,接口中定义属性与操作;get表示可读,set表示可写。
      2. 创建Agent类。
        a. 创建MBeanServer,相当于管理MBean的容器,创建方式有两种一获取JVM中默认启动的Mbean server 或者 自己创建。
        b. 创建ObjectName,用于标识唯一的资源MBean,格式为:"域名:name=MBean名称"。
        c. 绑定MBean与对应的ObjectName并注册到MBeanServer。
      至此即可通过JConsole管理本地的MBean的先关信息了,同事也可以提供其他的连接方式,如:
      3. rmi连接方式。
        a. 注册监听端口号。
        b. 创建JMXServiceURL,格式为:service:jmx:rmi://localhost:0/jndi/rmi://localhost:1099/jmxrmi(完整版) JMXServiceURL格式说明 。
        c. 创建jmxConnectorServer,绑定MBserver与Url。
      4. HtmlAdaptor连接管理方式(需要引入jmxtools.jar)。
        a. 创建Html适配器,并设置监听端口。
        b. 创建适配器ObjectName,绑定Html适配器并注册到MBeanServer。
        c. 开启适配器。


    具体使用详情,参考如下代码

    public static void init(LoggerContext loggerContext) throws Exception {
            mBeanServer = MBeanServerFactory.createMBeanServer(DOMAIN_NAME);
            // 注册服务
            ObjectName objectName = new ObjectName(DOMAIN_NAME + ":name=" + RELOAD_CONFIG_NAME);
            jmxConfigurator = new JMXConfigurator(loggerContext, mBeanServer, objectName);
            mBeanServer.registerMBean(jmxConfigurator, objectName);
    
            // htmlAdaptor 注册连接
            htmlAdaptorServer = new HtmlAdaptorServer();
            htmlAdaptorServer.setPort(HTML_PORT);
            objectName = new ObjectName(DOMAIN_NAME + ":name=" + CONNECTOR_NAME);
            mBeanServer.registerMBean(htmlAdaptorServer, objectName);
            htmlAdaptorServer.start();
    
            // rmi方式
            //这句话非常重要,不能缺少!注册一个端口,绑定url后,客户端就可以使用rmi通过url方式来连接JMXConnectorServer
            LocateRegistry.createRegistry(RMI_PORT);
            JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + RMI_PORT + "/logback_config");
            jmxConnectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mBeanServer);
            jmxConnectorServer.start();
        }

    5、JMXServiceURL格式说明
      (1)service:jmx:rmi://localhost:0/jndi/rmi://localhost:1099/jmxrmi
      蓝色部分可以省略掉
      (2)service:jmx: 这个是JMX URL的标准前缀,所有的JMX URL都必须以该字符串开头,否则会抛MalformedURLException
      (3)rmi: 这个是jmx connector server的传输协议,在这个url中是使用rmi来进行传输的
      (4)localhost:0 这个是jmx connector server的IP和端口,也就是真正提供服务的host和端口,可以忽略,那么会在运行期间随意绑定一个端口提供服务
      (5)jndi/rmi://localhost:1099/jmxrmi 这个是jmx connector server的路径,具体含义取决于前面的传输协议。比如该URL中这串字符串就代表着该jmx connector server的stub是使用 jndi api 绑定在 rmi://localhost:1099/jmxrmi 这个地址

    实际演示操作:

    1. Mbean准备  先建立需要连接的接口

    package com.gdut.jmx;
    
    /**
     * 实现接口, 可在jconsoler中调用属性
     */
    public interface HelloMBean {
    
        public String getName();
    
        public void setName(String name);
    
        public String getAge();
    
        public void setAge(String age);
    
        public void helloWorld();
    
        public void helloWorld(String str);
    
        public void getTelephone();
    
    }

    2, 实体类继承

    package com.gdut.jmx;
    
    import lombok.AllArgsConstructor;
    import lombok.NoArgsConstructor;
    
    /**
     * 必须实现 Mbean, 才可以进行注册
     */
    @NoArgsConstructor
    @AllArgsConstructor
    public class Hello implements HelloMBean {
    
        private String name;
        private String age;
    
        @Override
        public String getName() {
            System.out.println("get name::" + name);
            return name;
        }
        @Override
        public void setName(String name) {
            this.name = name;
            System.out.println("set name  " + name);
        }
        @Override
        public String getAge() {
            System.out.println("get age::" + age);
            return age;
        }
        @Override
        public void setAge(String age) {
            this.age = age;
            System.out.println("set age  " + age);
        }
        @Override
        public void helloWorld() {
            System.out.println("hello world");
        }
        @Override
        public void helloWorld(String str) {
            System.out.println("hello world " + str);
        }
        @Override
        public void getTelephone() {
            System.out.println("get telephone");
        }
    }

    3.使用java命令行指定

    package com.gdut.jmx;
    
    import java.lang.management.ManagementFactory;
    
    import javax.management.InstanceAlreadyExistsException;
    import javax.management.MBeanRegistrationException;
    import javax.management.MBeanServer;
    import javax.management.MalformedObjectNameException;
    import javax.management.NotCompliantMBeanException;
    import javax.management.ObjectInstance;
    import javax.management.ObjectName;
    
    public class HelloAgent {
    
        public static void main(String[] args) throws MalformedObjectNameException, NotCompliantMBeanException, InstanceAlreadyExistsException, MBeanRegistrationException, InterruptedException {
    
            MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    
            Hello hello = new Hello();
            // com.le.iris:type=ZhixinSource/QPS  域名:name=MBean名称
            ObjectName helloName  = new ObjectName("com.gdut.jmx:name=" + hello.getClass().getName());
    
            ObjectInstance objectInstance = server.registerMBean(hello, helloName);
    
            Thread.sleep(60*1000*1000);
        }
    }

    为Java程序开启JMX很简单,只要在运行Java程序的命令后面指定如下命令即可

    -Dcom.sun.management.jmxremote
    
    -Dcom.sun.management.jmxremote.port=8011
    
    -Dcom.sun.management.jmxremote.ssl=false
    
    -Dcom.sun.management.jmxremote.authenticate=false

    如果是使用eclipse开发测试,可以再eclipse 启动java项目默认没有开启jmx远程查看功能,如果需要看项目运行的线程内存使用量等信息,可以在eclipse启动参数中增加:(也可以单独配置选项的jconsole信息,在run-》run configurations-》选择对应的java application-》选择arguments选项-》在VM arguments中添加上面对应信息)

    使用jconsole工具使用进行监控

     Jconsole,Java Monitoring and Management Console。

     Jconsole是JDK自带的监控工具,在JDK/bin目录下可以找到。它用于连接正在运行的本地或者远程的JVM,对运行在java应用程序的资源消耗和性能进行监控,并画出大量的图表,提供强大的可视化界面。而且本身占用的服务器内存很小,甚至可以说几乎不消耗。

      JConsole 是一个内置 Java 性能分析器,可以从命令行(直接输入jconsole)或在 GUI shell (jdkin下打开)中运行。

      它用于对JVM中内存,线程和类等的监控。可使用JTop插件。它可以监控本地的jvm,也可以监控远程的jvm,也可以同时监控几个jvm。 

      这款工具的好处在于,占用系统资源少,而且结合Jstat,可以有效监控到java内存的变动情况,以及引起变动的原因。在项目追踪内存泄露问题时,很实用。 

    windows下直接cmd中输入:JConsole 后就可以弹出:

     进去之后

      可以通过操作MBean里面的属性和方法

     console输出:

     

     console输出:

    关于Jconsole请看这两篇:

       Jconsole与Jmx 分析JVM状况(上)

         Jconsole与Jmx 分析JVM状况(下)

    出处: JMX详解详细介绍及使用

       JMX超详细解读

  • 相关阅读:
    tar命令,vi编辑器
    Linux命令、权限
    Color Transfer between Images code实现
    利用Eclipse使用Java OpenCV(Using OpenCV Java with Eclipse)
    Matrix Factorization SVD 矩阵分解
    ZOJ Problem Set
    Machine Learning
    ZOJ Problem Set
    ZOJ Problem Set
    ZOJ Problem Set
  • 原文地址:https://www.cnblogs.com/myseries/p/11778166.html
Copyright © 2011-2022 走看看