Chinaunix首页 | 论坛 | 博客
  • 博客访问: 121777
  • 博文数量: 14
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 184
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-01 23:15
个人简介

我只是一个喜欢开发的测试,喜欢测试的开发,喜欢每天都知道得更多一些,更深入一些的感觉。。。。。

文章分类

全部博文(14)

文章存档

2015年(5)

2014年(2)

2013年(7)

分类: Java

2013-08-27 21:40:38

上一节说到了JMX所提供的9个管理接口,以及如何通过这些管理接口的方法来得到JVMOS的各种信息值,当时我们省略了怎样获取这些管理接口,这部分内容将在这一节里面展开。

 

概括的来说,获取JVMJMX管理接口一共有三种方法,如果把包含获取管理接口并通过管理接口进而获取信息的JVM称为监控者,而把被获取信息的JVM称为被监控者的话,那么这三种方法又与被监控者与监控者的远近有关,也就是说,这两者是否是同一个JVM,在同一台主机,还是分别在不同主机上,所能采用的方法是不同的。

 

在这一节中,我们首先说明一下,获取JMX管理接口的三种方法,然后使用这三种方法的一些应该注意的细节,最后是这三种方式的适用范围。


1.     ManagementFactory.get*MXBean()获取

ManagementFactory是一个工厂类,该类提供了一组静态方法都是用来获取JMX管理接口的,其中的get*MXBean()可以获取到JVM自身的管理接口,其中“*MXBean”为9个管理接口名之一,例如OperatingSystemMXBeanThreadMXBean等。

点击(此处)折叠或打开

  1. OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();

 

对于那些可能会有多个实例的管理接口类型,例如GarbageCollectorMXBean,是get*MXBeans()

点击(此处)折叠或打开

  1. List<GarbageCollectorMXBean> gcBeanList = ManagementFactory. getGarbageCollectorMXBeans ();

2.     MBeanServer+ManagementFactory.newPlatformMXBeanProxy()获取

首先用ManagementFactorygetPlatformMBeanServer()获取,然后再通过MBeanServer(MBeanServerConnection的子接口)ManagementFactorynewPlatformMXBeanProxy()方法获取到JMX管理接口,如下例中获取OperatingSystemMXBean

点击(此处)折叠或打开

  1. try{         
  2.    MBeanServer ms = ManagementFactory.getPlatformMBeanServer();         
  3.    OperatingSystemMXBean osBean = ManagementFactory.newPlatformMXBeanProxy(ms,         
  4.              ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME,         
  5.              OperatingSystemMXBean.class);
  6. }catch(IOException ioe){
  7.     System.out.println("a communication problem occurred when accessing the MBeanServerConnection.");
  8. }

对于那些可能会有多个实例的管理接口类型,例如GarbageCollectorMXBean,有一些细节需要进一步说明,由于这是调用ManagementFactory.newPlatformMXBeanProxy()方法的共性,我们放到方法说明部分的最后来说。


3.     MBeanServerConnection+ManagementFactory.newPlatformMXBeanProxy()获取

根据如何生成JMXServiceURL还可以进一步分成两种方法:

 

1)    PID生成JMXServiceURL

首先调用ConnectorAddressLink.importFrom()由进程号PID得到servicURL字符串,然后再用这个字符串生成一个新的JMXServiceURL实例:

点击(此处)折叠或打开

  1. try {            
  2.     String address = ConnectorAddressLink.importFrom(pid);            
  3.     JMXServiceURL jmxUrl = new JMXServiceURL(address);
  4. } catch (Exception e) {
  5.     e.printStackTrace();
  6. }

2)    IPJMX端口生成JMXServiceURL

IP和端口生成JMXServiceURL,首先被监控的那个JVM启动的时候要设置一些与JMX远程相关的选项,具体的说有以下几个:

-Dcom.sun.management.jmxremote=true

-Djava.rmi.server.hostname=192.168.91.166

-Dcom.sun.management.jmxremote.port=50013

-Dcom.sun.management.jmxremote.authenticate=false

-Dcom.sun.management.jmxremote.ssl=false

关于这些选项的含义,我在Jconsole监控本地及远程Java进程一文中已有说明,在此不再赘述,且网上也很多这方面的资料,请仔细查找参考。

 

其次用这种方法生成JMXServiceURL的时候,IPJMX端口组成的参数字符串是有规定格式的:

service:jmx:rmi:///jndi/rmi://IP:jmxPort/jmxrmi

其中:“service:jmx”为JMX URL的标准前缀;

            rmi”表示这个connector server的传输协议是rmi

           jndi/rmi://IP:jmxPort/ jmxrmi”是这个connector server的地址。

点击(此处)折叠或打开

  1. try {
  2.     String address = "service:jmx:rmi:///jndi/rmi://"+ ServerIP+":"+ServerPort+"/jmxrmi";             
  3.     JMXServiceURL jmxUrl = new JMXServiceURL(address);
  4. }catch(Exception e){
  5.     e.printStackTrace();
  6. }

 

得到了JMXServiceURL,接下来以此为参数调用JMXConnectorFactory.connect()生成JMXConnector,然后通过这个JMXConnectorgetMBeanServerConnection()得到MBeanServerConnection,最后同样ManagementFactorynewPlatformMXBeanProxy()方法获取到JMX管理接口:

点击(此处)折叠或打开

  1. JMXConnector connector = JMXConnectorFactory.connect(jmxUrl);
  2. MBeanServerConnection msc = connector.getMBeanServerConnection();
  3. OperatingSystemMXBean osBean = ManagementFactory.newPlatformMXBeanProxy(msc,
  4.                                               ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME,
  5.                                               OperatingSystemMXBean.class);

 

4.    ManagementFactory.newPlatformMXBeanProxy()获取多实例管理接口时的注意点

1)    获取已知名称的管理接口

对于已知名称的管理接口,可以用类似下面这样格式的字符串作为newPlatformMXBeanProxy()的第二个参数来得到实例:

java.lang:type=Type,name=Name

但为了防止出现not found in the connection.”的错,我们在这样做之前需要先验证一下在这MBeanServerConnection是否已经注册了有这个管理接口:

点击(此处)折叠或打开

  1. String mxbeanName = "java.lang:type="+type+",name="+name;
  2. try{         
  3.      ObjectName on = new ObjectName(mxbeanName);         
  4.      if(msc.isRegistered(on)){         
  5.            MemoryManagerMXBean mmBean = ManagementFactory.newPlatformMXBeanProxy(         
  6.                                                 msc, mxbeanName, MemoryManagerMXBean.class));         
  7.        }         
  8. }catch MalformedObjectNameException e){         
  9.        e.printStackTrace();         
  10. }

2)    获取某中类型的所有管理接口

很多时候我们并不知道被监控的JVM某类管理接口具体有哪些名称,我们只是想获取到这类管理接口的所有实例,那么我们可以java.lang:type=Type,name=*”创建一个ObjectName对象,然后用这个对象调用MBeanServerConnectionqueryNames()即可:

点击(此处)折叠或打开

  1. ArrayList<MemoryManagerMXBean> mmBeanList = new ArrayList<MemoryManagerMXBean>();
  2. try{         
  3.     ObjectName on = new ObjectName("java.lang:type="+type+",name=*");
  4.     Set mbeans = msc.queryNames(on, null);
  5.     Iterator iterator = mbeans.iterator();
  6.     while (iterator.hasNext()) {
  7.          mmBeanList.add(ManagementFactory.newPlatformMXBeanProxy(msc,iterator.next().toString(),
  8.                                        MemoryManagerMXBean.class));
  9.      }         
  10. } catch(MalformedObjectNameException e) {
  11.      e.printStackTrace();
  12. }

5.    三种获取JMX管理接口的方法适用范围



 

从上图中可以看到,我们之前说明的三种方法(其中第三种方法又包括两种生成JMXServiceURL方式),及其各种适用的范围:

1)   对于第一种和第二种方法,只能用于获取JVM本身的JMX管理接口;

2)    IP和端口生成JMXServiceURL的方法比较通用,可以用于获取本机上其他JVM的管理接口,也可以用于获取远程JVM的管理接口,但无论用于本机还是用于远程都需要设置JMX端口等选项,因此本机可以考虑用下面的方法;

3)    PID生成JMXServiceURL的方法只能用于获取本机上其他JVM的管理接口。


参考文献

1.    JDK6.0 Documentation

2.   http://songzi0206.iteye.com/blog/1541636

3.   http://jiangnanguying.iteye.com/blog/539697

4.   http://blog.sina.com.cn/s/blog_46d0362d0100qlke.html

5.   

6.   http://www.ibm.com/developerworks/library/j-mxbeans/

7.    JMX in Action

8.    

9.    JDK1.7中包含的JConsole源代码



阅读(5538) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~