首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

JMX引见 之一 JMX基础和Standard MBeans

2012-06-27 
JMX介绍 之一 JMX基础和Standard MBeans由于需要解决一个JMX的问题,回顾并总结了一下JMX相关的知识。?1. JM

JMX介绍 之一 JMX基础和Standard MBeans

由于需要解决一个JMX的问题,回顾并总结了一下JMX相关的知识。

?

1. JMX架构

简单来说,JMX的组成以及关系如下:

JMX客户端代码 ? ---> ? JMX connector ---> ? {.........网络........} ---> MBean Server ---> ?MBean(被调用对象)

其中JMX connector和MBean Server在JDK里面已经提供,我们只需要实现被调用对象,已经调用的代码。而且,在JDK里面已经提供了非常多的MBean,可以直接使用。

?

2. 启用JMX

JMX的用处就是远程监控和管理。最普遍的就是JVM的运行状态的监控。

在我们的系统中,也可以有很多用处,例如,需要对一些运行状态或者参数进行查看或修改,特别是系统调优时,有几种处理方法或算法,可以通过JMX提供方便的修改,可以实时的看到结果。

?

要启用JMX,只需要在java的启动参数里面加上下面的参数

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

?

如果是tomcat,就用ctalena.sh start -Dcom...... ?这样就可以。

?

然后就可以运行jconsole,连接到远程的tomcat server。

?

3. MBean类型

在JMX标准中,定义了5中类型的MBean:

?

    Standard MBeansDynamic MBeansOpen MBeansModel MBeansMXBeans

    ?

    至于各种类型是什么意思,在JDK的tutorial中没有说明,我也懒得找其他资料,我觉得只是使用的话,就只需要知道标准的MBeans和MXBeans就可以。Standard MBeans就是最基础的MBean,通过它可以了解MBea的工作方式,对MBean有一个了解。

    如果大家了解远程调用,就应该知道,一般远程的客户端的代码中要包含所要调用对象的存根(stub),也就是要包含远程对象的interface。在使用Standard MBeans时,我们就需要在调用端包含被调用的远程的MBean对象的接口。

    ?

    而在MXBeans类型中,客户端不需要知道远程对象的类型,更不需要包含它的接口,就能够通过一些MXBeans中预定义的集合类型,就能够知道如何调用远程对象,需要的参数以及类型等。

    在后面的例子中就可以看到MXBeans和普通MBean的区别。

    ?

    ?

    3. Standard MBeans

    使用这种类型的MBeans,首先,需要定义一个接口,也就是MBean接口,如下:

    ?

    ?

    package com.example;  public interface HelloMBean {      public void sayHello();     public int add(int x, int y);         public String getName();          public int getCacheSize();     public void setCacheSize(int size); } 
    ?

    在这个接口中,定义了5个方法,但是,只有add和syHello两个方法才会被当做是这个Mbean的接口。

    根据JMX标准的定义,所有的getter方法,即以get开头,不返回void的方法,都不是MBean对外提供的方法。即使get方法没有对应的成员变量,只是一个普通的get方法,也会被认为是getter方法,而不是MBean的接口。同样,setter方法也是。

    然后,根据上面的接口类中的getter和setter方法定义,JMX对认为这个MBean对象有两个属性,即name和cacheSize。

    ?

    接下来就是这个接口的实现:

    ?

    ?

    package com.example.mbeans;  public class Hello implements HelloMBean {     public void sayHello() {         System.out.println("hello, world");     }      public int add(int x, int y) {         return x + y;     }      public String getName() {         return this.name;     }       public int getCacheSize() {         return this.cacheSize;     }      public synchronized void setCacheSize(int size) {         this.cacheSize = size;          System.out.println("Cache size now " + this.cacheSize);     }      private final String name = "Reginald";     private int cacheSize = DEFAULT_CACHE_SIZE;     private static final int DEFAULT_CACHE_SIZE = 200; } 
    ?

    实现没什么可说的。

    ?

    然后就是注册这个MBean:

    ?

    ?

    import java.lang.management.*; import javax.management.*;  public class Main {     public static void main(String[] args) throws Exception {        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();        ObjectName name = new ObjectName("com.example.mbeans:type=Hello");        Hello mbean = new Hello();        mbs.registerMBean(mbean, name);        System.out.println("Waiting forever...");       Thread.sleep(Long.MAX_VALUE);    } } 
    ?

    它用ManagementFactory生成一个MBean server,会在一个端口上监听JMX请求,我这里是63560,不知道这个默认端口是不是固定的。但是,这个端口不是用来远程连接的。

    ?

    编译好所有的类以后,运行Main,然后,就可以打开jconsole,就能看到有一个本地的Main进程,连接上以后,就能看到有两个属性,以及2个操作。

    ?

    我们还可以在java里面使用发送jmx请求的方式来调用MBeanserver里面的对象方法。要在java程序中使用,我们就需要在运行Main的时候,加上JMX的参数,这样才能连接。

    ?

    下面就是client的代码:

    ?

    import javax.management.JMX;import javax.management.MBeanServerConnection;import javax.management.ObjectName;import javax.management.remote.JMXConnector;import javax.management.remote.JMXConnectorFactory;import javax.management.remote.JMXServiceURL;public class HelloClient {public static void main(String[] args) {try {JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8888/jmxrmi");JMXConnector jmxc = JMXConnectorFactory.connect(url, null);MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();ObjectName mbeanName = new ObjectName("com.example.mbeans:type=Hello");HelloMBean mbeanProxy = JMX.newMBeanProxy(mbsc, mbeanName,HelloMBean.class, true);System.out.println("CacheSize = " + mbeanProxy.getCacheSize());mbeanProxy.setCacheSize(150);System.out.println("CacheSize = " + mbeanProxy.getCacheSize());System.out.println("Invoke sayHello() in Hello MBean...");mbeanProxy.sayHello();System.out.println("add(2, 3) = " + mbeanProxy.add(2, 3));} catch (Exception e) {e.printStackTrace();}}}
    ?

    ?

    注意,上面的代码中,端口是启用JMX时配置的端口,创建mbeanName时使用的名字“com.example.mbeans:type=Hello” 必须和Main中注册时使用的名字一致。

    ?

    还有,我们需要import 进来HelloMBean接口类,一般情况下,是需要把远程对象的接口打包成一个jar,然后包含在客户端的lib目录中。在上面的client代码中,因为我的HelloMbean类是直接复制过来的,而且都在同一个包下,所以没有显式的import进来。

    ?

热点排行