• 测试开发进阶——常用中间件概念——JMX监听器理解


    JMX的简介

    JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架 ,从Java5.0开始引入到标准Java技术平台中。

    JMX是一套标准的代理和服务,实际上,用户可以在任何Java应用程序中使用这些代理和服务实现管理。

    从官方的文档上来看,他就是一个框架,和JPA、JMS是一样的,和我们平时使用的Spring、Hibernate也没有什么区别。

    我个人的理解是JMX让程序有被管理的功能,例如你开发一个WEB网站,它是在24小时不间断运行,那么你肯定会对网站进行监控,如每天的UV、PV是多少;

    又或者在业务高峰的期间,你想对接口进行限流,就必须去修改接口并发的配置值。

    它的API在一下两个地方:

    java.lang.management:

    javax.management.*:包括javax.management.loading、javax.management.modelmbean等;

     

    应用场景:

    1、用来管理应用程序的配置项,可以在运行期动态改变配置项的值,而不用妨碍程序的运行,这对与许多可靠性要求较高的应用来说非常方便。

         可以通过jconsole等JMX客户端工具动态改变配置项的值。

    2、用来对应用程序的运行状态进行监控,比如对一个大型交易处理程序,要监控当前有多少交易在排队中,每笔交易的处理时间是多少,平均每处理一笔交易要花多少时间等等。

    中间件软件WebLogic的管理页面就是基于JMX开发的,而JBoss则整个系统都基于JMX构架。

    对于一些参数的修改,网上有一段描述还是比较形象的:

    1、程序初哥一般是写死在程序中,到要改变的时候就去修改代码,然后重新编译发布。

    2、程序熟手则配置在文件中(JAVA一般都是properties文件),到要改变的时候只要修改配置文件,但还是必须重启系统,以便读取配置文件里最新的值。

    3、程序好手则会写一段代码,把配置值缓存起来,系统在获取的时候,先看看配置文件有没有改动,如有改动则重新从配置里读取,否则从缓存里读取。

    4、程序高手则懂得物为我所用,用JMX把需要配置的属性集中在一个类中,然后写一个MBean,再进行相关配置。另外JMX还提供了一个工具页,以方便我们对参数值进行修改。

    jmx架构基本概念

    从上面的架构图可以看到JMX主要分三层,分别是:

    1、设备层(Instrumentation Level)

    主要定义了信息模型。在JMX中,各种管理对象以管理构件的形式存在,需要管理时,向MBean服务器进行注册。该层还定义了通知机制以及一些辅助元数据类。

    设备层其实就是和被管设备通信的模块,对于上层的管理者来说,Instrumentation 就是设备,具体设备如何通信,是采用SNMP,还是采用ICMP,是MBean的事情。

    该层定义了如何实现JMX管理资源的规范。

    一个JMX管理资源可以是一个Java应用、一个服务或一个设备,它们可以用Java开发,或者至少能用Java进行包装,并且能被置入JMX框架中,从而成为JMX的一个管理构件(Managed Bean),简称MBean。

    管理构件可以是标准的,也可以是动态的,标准的管理构件遵从JavaBeans构件的设计模式;动态的管理构件遵从特定的接口,提供了更大的灵活性。

    在JMX规范中,管理构件定义如下:它是一个能代表管理资源的Java对象,遵从一定的设计模式,还需实现该规范定义的特定的接口。

    该定义了保证了所有的管理构件以一种标准的方式来表示被管理资源。

    管理接口就是被管理资源暴露出的一些信息,通过对这些信息的修改就能控制被管理资源。一个管理构件的管理接口包括:

    1) 能被接触的属性值

    2) 能够执行的操作

    3) 能发出的通知事件

    4) 管理构件的构建器

    本文着重介绍最基本也是用的最多的Standard Mbean,至于其它的如Dynamic MBean、Model MBean暂时不介绍,

    Standard MBean是最简单的MBean,它管理的资源必须定义在接口中,然后MBean必须实现这个接口。

    它的命名也必须遵循一定的规范,例如我们的MBean为Hello,则接口必须为HelloMBean。

    2、代理层(Agent Level)

    Agent层 用来管理相应的资源,并且为远端用户提供访问的接口。Agent层构建在设备层之上,并且使用并管理设备层内部描述的组件。

    Agent层主要定义了各种服务以及通信模型。该层的核心是 MBeanServer,所有的MBean都要向它注册,才能被管理。

    注册在MBeanServer上的MBean并不直接和远程应用程序进行通信,他们通过 协议适配器(Adapter) 和 连接器(Connector) 进行通信。

    通常Agent由一个MBeanServer和多个系统服务组成。JMX Agent并不关心它所管理的资源是什么。

    3、分布服务层(Distributed Service Level)

    分布服务层关心Agent如何被远端用户访问的细节。它定义了一系列用来访问Agent的接口和组件,包括Adapter和Connector的描述。

    ==================================================

    JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架。

    JMX是一套标准的代理和服务,实际上,用户可以在任何Java应用程序中使用这些代理和服务实现管理。

    JMX的前身是JMAPI。

    JMX致力于解决分布式系统管理的问题,因此,能够适合于各种不同的环境是非常重要的。

    为了能够利用功能强大的Java计算环境解决这一的问题,Sun公司扩充了Java基础类库,开发了专用的管理类库。

    JMX是一种应用编程接口,可扩充对象和方法的集合体,可以用于跨越一系列不同的异构操作系统平台、

    系统体系结构和网络传输协议,灵活的开发无缝集成的系统、网络和服务管理应用它提供了用户界面指导、Java类和开发集成系统、网络及网络管理应用的规范。

    管理对象是JMX应用程序的核心。

    JMX结构包括:支持Java的Web浏览器用户接口,管理运行模块ARM(Admin Runtime Module)和应用。

    这三个部件之间通过RMI(Remote Method Invocation)进行通信。

    这里需要说明的是,RMI是使得一个Java虚拟机(JVM)上运行的程序可以调用远程服务器上另一个JVM总的对象。

    用户接口用来发布管理操作,这些操作可以间接的通过浏览器或通过单独的应用程序来激发。

    管理运行模块用来给应用提供实例化的管理对象。它包括Agent对象接口,通知接口和被管数据接口。应用指的是那些被管设备单元。

    JMX是一个完整的网络管理应用程序开发环境,

    它同时提供了:厂商需要收集的完整的特性清单,可生成资源清单表格,图形化的用户接口;访问SNMP的网络API;主机间远程过程调用;数据库访问方法。

    JMX这一轻型的管理基础结构,价值在于对被管理资源的服务实现了抽象,提供了低层的基本类集合,开发人员在保证大多数的公共管理类的完整性和一致性的前提下,进行扩展以满足特定网络管理应用的需要。

    JMX注重于构造管理工具的软件框架,并尽量采用已成熟的技术。

    JMX体系被分成三个层次

    表现层
    代理层
    分布式服务层


    表现层


    表现层定义的是JMX可管理资源所在的层。

    这些已管理的资源可以编写或封装为MBean。

    MBean分为四种类型: 标准、动态、开放、模型

    代理层


    定义的是MBean向应用程序施加管理的层。包括MBean服务器和代理服务的定义。还至少包括一个协议适配器或连接器。

    代理的组成: 一个MBean服务器 。要管理的MBean 。作为MBean实现的代理服务 。至少一个协议适配器MBean

    在JMX中,最小的可管理单元是MBean。

    MBean不是一个真正的接口和类,而是必须准循的设计模式以确保资源是一个兼容的MBean。

    MBean的激活方法:

    invoke()方法是管理应用程序用于激活MBean的方法的手段。 invoke()方法有三个参数,分别是方法的名称、表示属性的对象数组和描述方法签名的一个字符串数组。它与使用Java Reflection Api 激活方法的方式类似。

    Notification(通知)模型:

    MBean的通知模型类似与Java事件的监听器模型。 MBean或管理应用程序可以作为MBean事件的监听器注册。 通知支持由两个基本的概念组成,即广播器和监听器。

    MBean服务器
    MBean服务器用于注册可管理的MBean。

    所有对MBean的请求或查询都是通过MBean服务器实施的。

    代理服务
    代理服务是一些特殊的函数,代理把这些服务提供给MBean,这些代理服务独立于任何MBean。

    一个代理可以提供四种主要的服务:

    动态装载:允许代理通过下载这个Bean的类动态实例化MBean,这与装载applet的方式类似。
                     JMX使用m-let这个标记指定期望动态装载的MBean的位置。

    监控:允许代理通知有关的监听器监控一个MBean的属性值的变化

    JMX允许使用三种基本类型的监控程序:

    (1)CounterMonitor:该程序可以观察类型方面的变化,比如Byte类似或Integer类型

    (2)GaugeMonitor:该程序可以观察类型方面的变化,比如Byte类似或Integer类型,还可以在到达上下阀值时进行报告。

    (3)StringMonitor:该程序可以观察java.lang.String类型的变化。

    计时器:允许预设的时间间隔发送通知,可以作为一个调度程序

    关系:允许创建和维护MBean之间的关系

    分布式服务层


    包含协议适配器和连接器两种类型的组件,通过它们连接到外部的应用,如RMI管理应用、基于浏览器的管理控制等

    协议适配器和连接器


    协议适配器是代理与管理客户通信的手段,每个通信的协议都可能不同。


    它们都是管理客户与MBean交互的方式。

    JMX的好处


    可减少对JAVA应用实施管理的投资,

    提供了一个可伸缩的管理框架

    集成现有的管理方案:如:WBEM,SNMP,TMN


    使用现有的标准JAVA技术


    能使用未来的一些管理概念:如Jini连接技术、通用即插即用、服务定位协议(Service Location Protocol)


    只定义了一些可以访问的接口

    ===================================================================

    转载:http://www.tianshouzhi.com/api/tutorials/jmx

    MX是Java Management Extensions 的简写,即Java管理扩展。从名字中就可以看出,这门技术是对Java应用程序和JVM进行监控和管理的。

    在企业实际开发过程中,所有的程序都是需要进行监控的。没有监控,程序就相当于是裸奔。

    在一些小公司可能没有监控,只注重于功能,但是在大公司中,没有监控是绝对不可能的。

    JMX是Java官方提供的一套用于监控Java程序和JVM运行时状态的标准API。通过JMX,我们可以监控的内容包括:

    1、服务器中各种资源的使用情况:如CPU、内存等

    2、JVM内存使用情况

    3、JVM中的线程情况

    4、JVM中加载的类

    ....

    ===============================================================================

    转载:https://www.cnblogs.com/dongguacai/p/5900507.html

     

    一、JMX的定义  

      JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架。JMX是一套标准的代理和服务,实际上,用户可以在任何Java应用程序中使用这些代理和服务实现管理。这是官方文档上的定义,我看过很多次也无法很好的理解。我个人的理解是JMX让程序有被管理的功能,例如你开发一个WEB网站,它是在24小时不间断运行,那么你肯定会对网站进行监控,如每天的UV、PV是多少;又或者在业务高峰的期间,你想对接口进行限流,就必须去修改接口并发的配置值。

      应用场景:中间件软件WebLogic的管理页面就是基于JMX开发的,而JBoss则整个系统都基于JMX构架。

    对于一些参数的修改,网上有一段描述还是比较形象的:

    1、程序初哥一般是写死在程序中,到要改变的时候就去修改代码,然后重新编译发布。

    2、程序熟手则配置在文件中(JAVA一般都是properties文件),到要改变的时候只要修改配置文件,但还是必须重启系统,以便读取配置文件里最新的值。

    3、程序好手则会写一段代码,把配置值缓存起来,系统在获取的时候,先看看配置文件有没有改动,如有改动则重新从配置里读取,否则从缓存里读取。

    4、程序高手则懂得物为我所用,用JMX把需要配置的属性集中在一个类中,然后写一个MBean,再进行相关配置。另外JMX还提供了一个工具页,以方便我们对参数值进行修改。

    二、JMX架构图:

    从图中我们可以看到,JMX的结构一共分为三层:

    1、基础层:主要是MBean,被管理的资源。

    MBean分为如下四种,我接下来主要介绍standard MBean

    类型 描述
    standard MBean 这种类型的MBean最简单,它能管理的资源(包括属性,方法,时间)必须定义在接口中,然后MBean必须实现这个接口。它的命名也必须遵循一定的规范,例如我们的MBean为Hello,则接口必须为HelloMBean。
    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中。后面的例子会有详细介绍

    2、适配层:MBeanServer,主要是提供对资源的注册和管理。

    3、接入层:提供远程访问的入口。

    接下来我这里会用程序来介绍三种访问JMX的方式:

    三、JDK的小工具Jconsole访问

     1、 首先定义一个MBean接口,接口的命名规范为以具体的实现类为前缀(这个规范很重要)

    复制代码
     1 package jmx;
     2 
     3 public interface HelloMBean
     4 {
     5      public String getName();
     6         
     7      public void setName(String name);
     8         
     9      public String getAge();
    10 
    11      public void setAge(String age);
    12         
    13      public void helloWorld();
    14         
    15      public void helloWorld(String str);
    16         
    17      public void getTelephone();
    18 }
    复制代码

    2、定义一个实现类,实现上面的接口:

    复制代码
     1 package jmx;
     2 
     3 /*
     4  * 该类名称必须与实现的接口的前缀保持一致(即MBean前面的名称
     5  */
     6 public class Hello implements HelloMBean
     7 {
     8     private String name;
     9         
    10     private String age;
    11 
    12     public void getTelephone()
    13     {
    14         System.out.println("get Telephone");
    15     }
    16 
    17     public void helloWorld()
    18     {
    19         System.out.println("hello world");
    20     }
    21 
    22     public void helloWorld(String str)
    23     {
    24         System.out.println("helloWorld:" + str);
    25     }
    26 
    27     public String getName()
    28     {
    29         System.out.println("get name 123");
    30         return name;
    31     }
    32 
    33     public void setName(String name)
    34     {
    35         System.out.println("set name 123");
    36         this.name = name;
    37     }
    38 
    39     public String getAge()
    40     {
    41         System.out.println("get age 123");
    42         return age;
    43     }
    44 
    45     public void setAge(String age)
    46     {
    47         System.out.println("set age 123");
    48         this.age = age;
    49     }      
    53 }
    复制代码

    3、定义agent层:

    复制代码
     1 package jmx;
     2 
     3 import java.lang.management.ManagementFactory;
     4 
     5 import javax.management.JMException;
     6 import javax.management.MBeanServer;
     7 import javax.management.ObjectName;
     8 
     9 public class HelloAgent
    10 {
    11     public static void main(String[] args) throws JMException, Exception
    12     {
    13          MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    14          ObjectName helloName = new ObjectName("jmxBean:name=hello");
    15          //create mbean and register mbean
    16          server.registerMBean(new Hello(), helloName);
    17          Thread.sleep(60*60*1000);
    18     }
    19 }
    复制代码

    1、其中第13行是通过工厂类获取MBeanServer,用来做MBean的容器 。

    2、第14行中的ObjectName中的取名是有一定规范的,格式为:“域名:name=MBean名称”,其中域名和MBean的名称可以任意取。这样定义后,就可以唯一标识我们定义的这个MBean的实现类了。

    3、第16行是将Hello这个类注入到MBeanServer中,注入需要创建一个ObjectName类 

    这样,一个简单的JMX的DEMO已经写完了,现在我们通过JDK提供的Jconsole来进行操作。

    1、首先在自己的本地路径下:C:Program Files (x86)Javajdk1.6.0_43in找到jconsole.exe这个小工具,双击打开:

    2、双击打开我们的本地进程:HelloAgent:

    3.在这个界面上,我们可以给程序中HelloMBean的属性赋值,也可以调用其中的方法:

    4、控制台打印如下:

    四、通过JMX提供的工具页访问

    这里,我们复用上面的接口和实现类,只需要改动适配层,这里需要到导入外部jar包jdmk

    复制代码
    package jmx;
    
    import java.lang.management.ManagementFactory;
    
    import javax.management.JMException;
    import javax.management.MBeanServer;
    import javax.management.ObjectName;
    
    import com.sun.jdmk.comm.HtmlAdaptorServer;
    
    public class HelloAgent
    {
        public static void main(String[] args) throws JMException, Exception
        {
             MBeanServer server = ManagementFactory.getPlatformMBeanServer();
             ObjectName helloName = new ObjectName("jmxBean:name=hello");
             //create mbean and register mbean
             server.registerMBean(new Hello(), helloName);
             
             ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082");   
             HtmlAdaptorServer adapter = new HtmlAdaptorServer();   
             server.registerMBean(adapter, adapterName);  
             adapter.start();
        }
    }
    复制代码

    我们访问地址:http://localhost:8082,点击name=hello:

    1、在这里创建一个AdaptorServer,这个类将决定MBean的管理界面,这里用最普通的Html型界面。AdaptorServer其实也是一个MBean。 

    2、我们可以看到这个工具页,其实与我们上一个案例中的Jconsole中的管理界面类似,都可以操作资源中的属性和方法。

    五、通过客户端程序进行远程访问

     1、这里需要对agent进行修改,增加ip和porta绑定部分的逻辑

    复制代码
    package jmxTest;
    
    import java.io.IOException;
    import java.lang.management.ManagementFactory;
    import java.rmi.RemoteException;
    import java.rmi.registry.LocateRegistry;
    
    import javax.management.JMException;
    import javax.management.MBeanServer;
    import javax.management.ObjectName;
    import javax.management.remote.JMXConnectorServer;
    import javax.management.remote.JMXConnectorServerFactory;
    import javax.management.remote.JMXServiceURL;
    
    public class HelloAgent
    {
        public static void main(String[] args) throws JMException, NullPointerException
        {
            MBeanServer server = ManagementFactory.getPlatformMBeanServer();
            ObjectName helloName = new ObjectName("jmxBean:name=hello");
            //create mbean and register mbean
            server.registerMBean(new Hello(), helloName);
            try
            {
                //这个步骤很重要,注册一个端口,绑定url后用于客户端通过rmi方式连接JMXConnectorServer
                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);
                System.out.println("begin rmi start");
                jcs.start();
                System.out.println("rmi start");
            }
            catch (RemoteException e)
            {
                e.printStackTrace();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
          
    }
    }
    复制代码

      写到这里,如果没有client进行远程连接,可以使用Jconsole进行远程访问:

    2、客户端Client程序,用于与agent进行远程连接:

    复制代码
     1 package jmx;
     2 
     3 import java.io.IOException;
     4 
     5 import javax.management.Attribute;
     6 import javax.management.MBeanServerConnection;
     7 import javax.management.MBeanServerInvocationHandler;
     8 import javax.management.ObjectName;
     9 import javax.management.remote.JMXConnector;
    10 import javax.management.remote.JMXConnectorFactory;
    11 import javax.management.remote.JMXServiceURL;
    12 
    13 
    14 public class Client
    15 {
    16     public static void main(String[] args) throws IOException, Exception, NullPointerException
    17     {
    18         JMXServiceURL url = new JMXServiceURL
    19             ("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");
    20         JMXConnector jmxc = JMXConnectorFactory.connect(url,null);
    21         
    22         MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
    23         //ObjectName的名称与前面注册时候的保持一致
    24         ObjectName mbeanName = new ObjectName("jmxBean:name=hello");
    25         
    26         System.out.println("Domains ......");
    27         String[] domains = mbsc.getDomains();
    28         
    29         for(int i=0;i<domains.length;i++)
    30         {
    31             System.out.println("doumain[" + i + "]=" + domains[i] );
    32         }
    33         
    34         System.out.println("MBean count = " + mbsc.getMBeanCount());
    35         //设置指定Mbean的特定属性值
    36         //这里的setAttribute、getAttribute操作只能针对bean的属性
    37         //例如对getName或者setName进行操作,只能使用Name,需要去除方法的前缀
    38         mbsc.setAttribute(mbeanName, new Attribute("Name","杭州"));
    39         mbsc.setAttribute(mbeanName, new Attribute("Age","1990"));
    40         String age = (String)mbsc.getAttribute(mbeanName, "Age");
    41         String name = (String)mbsc.getAttribute(mbeanName, "Name");
    42         System.out.println("age=" + age + ";name=" + name);
    43         
    44         HelloMBean proxy = MBeanServerInvocationHandler.
    45             newProxyInstance(mbsc, mbeanName, HelloMBean.class, false);
    46         proxy.helloWorld();
    47         proxy.helloWorld("migu");
    48         proxy.getTelephone();
    49         //invoke调用bean的方法,只针对非设置属性的方法
    50         //例如invoke不能对getName方法进行调用
    51         mbsc.invoke(mbeanName, "getTelephone", null, null);
    52         mbsc.invoke(mbeanName, "helloWorld", 
    53             new String[]{"I'll connect to JMX Server via client2"}, new String[]{"java.lang.String"});
    54         mbsc.invoke(mbeanName, "helloWorld", null, null);
    55     }
    56 }
    复制代码

    a、在35到41行,是对属性进行赋值和取值,这里我们不能直接调用方法,而是通过setAttribute、getAttrubute方法来进行操作,则属性的首字母要大写。

    b、对资源里面的方法进行操作有两种方式:一是通过代理直接调用方法;二是通过JAVA的反射注入的方式进行方法的调用。

    下面我们来看看执行结果,先执行agent,再执行客户端:

    c、client的控制台打印结果:

    d、agent控制台打印结果:

     六、Notification

     MBean之间的通信是必不可少的,Notification就起到了在MBean之间沟通桥梁的作用。JMX 的通知由四部分组成:

    1、Notification这个相当于一个信息包,封装了需要传递的信息

    2、Notification broadcaster这个相当于一个广播器,把消息广播出。

    3、Notification listener 这是一个监听器,用于监听广播出来的通知信息。

    4、Notification filiter 这个一个过滤器,过滤掉不需要的通知。这个一般很少使用。

    这里我们使用日常打招呼的场景:jack与我偶遇,jack说:hi;我礼貌的回答:hello,jack。

    这里我们先分别创建两个资源:

    复制代码
    package jmx;
    
    /*
     * 该类名称必须与实现的接口的前缀保持一致(即MBean前面的名称
     */
    public class Hello implements HelloMBean
    {
        private String name;
    
        public String getName()
        {
            return name;
        }
    
        public void setName(String name)
        {
            this.name = name;
        }
    
        public void printHello()
        {
            System.out.println("Hello World, " + name);
        }
    
        public void printHello(String whoName)
        {
            System.out.println("Hello , " + whoName);
        }
    }
    复制代码
    复制代码
    package jmx;
    
    /*
     * 接口名必须以MBean结尾
     */
    public interface HelloMBean
    {
        public String getName();   
        
        public void setName(String name);   
      
        public void printHello();   
      
        public void printHello(String whoName);
    }
    复制代码
    复制代码
    package jmx;
    
    import javax.management.Notification;
    import javax.management.NotificationBroadcasterSupport;
    
    public class Jack extends NotificationBroadcasterSupport implements JackMBean
    {
        private int seq = 0;
        public void hi()
        {
             //创建一个信息包
            Notification notify = 
                //通知名称;谁发起的通知;序列号;发起通知时间;发送的消息
                new Notification("jack.hi",this,++seq,System.currentTimeMillis(),"jack");
            sendNotification(notify);
        }
    
    }
    复制代码
    package jmx;
    
    public interface JackMBean
    {
        public void hi();
    }

    这里的类Jack不仅实现了MBean接口,还继承了NotificationBroadcasterSupport。jack在这里创建并发送了一个消息包。

    复制代码
    package jmx;
    
    import javax.management.Notification;
    import javax.management.NotificationListener;
    
    public class HelloListener implements NotificationListener
    {
    
        public void handleNotification(Notification notification, Object handback)
        {
            if(handback instanceof Hello)
            {
                Hello hello = (Hello)handback;
                hello.printHello(notification.getMessage());
            }
        }
        
    }
    复制代码
    复制代码
    package jmx;
    
    import java.lang.management.ManagementFactory;
    
    import javax.management.JMException;
    import javax.management.MBeanServer;
    import javax.management.ObjectName;
    
    public class HelloAgent
    {
        public static void main(String[] args) throws JMException, Exception
        {
            MBeanServer server = ManagementFactory.getPlatformMBeanServer();
            ObjectName helloName = new ObjectName("yunge:name=Hello");    
            Hello hello=new Hello();          
            server.registerMBean(hello, helloName);  
            Jack jack = new Jack();
            server.registerMBean(jack, new ObjectName("jack:name=Jack"));
            jack.addNotificationListener(new HelloListener(), null, hello);
            Thread.sleep(500000);
        }
    }
    复制代码

    我们用Jconsole来进行访问:

    这里我们可以看到有两个MBean,一个是yunge,一个是jack。我们执行jack的hi方法后,去看下控制台上的打印信息;

     七、linux下利用JMX监控Tomcat

      利用JMX监控Tomcat,就是相当于部署在tomcat上的应用作为服务端,也就是被管理资源的对象。然后通过程序或者jconsole远程连接到该应用上来。远程连接需要服务器端提供ip和port。如果需要加密访问的话,还需要配置用户名、密码等参数。

    主要是在tomcat下的文件catalina.sh中进行一些环境变量的配置配置:

     

    -Dcom.sun.management.jmxremote=true                 相关 JMX 代理侦听开关

    -Djava.rmi.server.hostname                                     服务器端的IP
    -Dcom.sun.management.jmxremote.port=29094             相关 JMX 代理侦听请求的端口

    -Dcom.sun.management.jmxremote.ssl=false              指定是否使用 SSL 通讯

    -Dcom.sun.management.jmxremote.authenticate=false     指定是否需要密码验证

    这样就可以通过客户端或者jconsole对tomcat进行监控。

  • 相关阅读:
    ubuntu系统安装微信小程序开发工具
    【工具】vscode-代码编辑器详解
    微信小程序开发
    webpack基本配置
    vue相关知识
    史上最强vue总结~万字长文---面试开发全靠它了
    ES6——字符串
    ES6——Proxy与Reflect
    ES6——Map与Set
    ES6——Symbol
  • 原文地址:https://www.cnblogs.com/xiaobaibailongma/p/15335146.html
Copyright © 2020-2023  润新知