JMX详解

一、概念

JMX是java1.5中引入的新特性。JMX全称为“Java Management  Extension”,即Java管理扩展。


二、为什么需要JMX?

为了说明白JMX的作用,我们先了解一下什么是“管理系统(Management System)”。

        随着企业IT规模的不断增长,IT资源(IT Resource)数量不断增加,IT资源的分布也越来越分散。可以想象,甚至对于一家只有几百台PC的公司的IT管理人员来说,分发一个安全补丁并且保证其在每台PC上的安装,如果只依赖人工来完成那简直就是一场噩梦。这样,IT管理系统就应运而生。

        然而,CPU、网卡、存储阵列是IT资源;OS、MS Office、Oracle database、IBM Websphere也是IT资源。IT管理系统若要对这些IT资源进行管理,就必须对这些管理对象有所了解。所以我们要给每个IT资源配一个翻译,于是就有了下面的管理系统架构。


上图中,Agent/SubAgent起到的就是翻译的作用:把IT资源报告的消息以管理系统能理解的方式传送出去。

为什么需要Agent和SubAgent两层体系呢?有两个现实原因:

1、管理系统一般是一个中央控制的控制软件,而SubAgent直接监控一些,往往和这些资源分布在同一物理位置。当这些SubAgent把状态信息传输到管理系统或者传达管理系统的控制指令时,需要提供一些网络传输的功能。

2、管理系统的消息是有一定规范的,消息的翻译本身是件复杂而枯燥的事情。

一般来说,管理系统会将同一物理分布或者功能类似的SubAgent分组成一组,由一个共用的Agent加以管理。在这个Agent里封装了1和2的功能。

JMX就是Java管理系统的一个标准、一个规范,也是一个接口,一个框架。是管理系统中Management System与Resource之间的桥梁。

        一直以来。Java开发人员必须通过一些底层的JVM API,比如JVMPI 和 JVMTI等。才能监测Java程序运行过程中的JVM和系统的一系列情况,这种方式需要调用大量的C程序和JNI调用,开发效率十分低下。JMX的提出,让JDK中开发自检测程序成为可能,也提供了大量轻量级的监测JVM和运行中对象/线程的方式,从而提供了Java语言自己的管理监测能力。


三、JMX是什么样子的?

1、JMX的架构


JMX是管理系统和资源之间的一个接口,它定义了管理系统和资源之间交互的标准。javax.management.MBeanServer实现了Agent的功能,以标准的方式给出了管理系统访问JMX框架的接口。而javax.management.MBeans实现了SubAgent的功能,以标准的方式给出了JMX框架访问资源的接口。

从类库的层次上看,JMX包括了核心类库java.lang.management和javax.management包。java.lang.management包提供了基本的VM监控功能。而javax.management包则向用户提供了扩展功能。

2、JVM基本框架


JMX规范可以分为三层:设备层,代理层,分布式服务层。

设备层规范定义了编写可由JMX管理的资源的标准,即如何写MBean;

代理层规范定义了创建代理的规范,封装了MBean Server;

分布式服务层主要定义了对代理层进行操作的管理接口和构件。

JMX使用Java Bean模式来传递信息。JMX使用的是MBean,其内部包含了数据信息,这些信息可能是:应用程序配置信息、模块信息、系统信息、统计信息等。另外,MBean也可以设立可读写的属性、直接操作某些函数甚至启动MBean可发送的notification等。MBean包括Standard, MXBean,Dynamic,Model ,Open等几种分类。

3、JMX模拟管理程序

下面程序展现了,如何实现一个标准MBean来监测某个服务器ServerImpl状态。

ServerImpl的实现如下:

public class ServerImpl {
	public final long startTime;
	public ServerImpl() {
		startTime = System.currentTimeMillis();
	}
}
使用ServerMonitor类来监测ServerImpl的状态,实现如下:

public class ServerMonitor implements ServerMonitorMBean {
	private final ServerImpl target;
	public ServerMonitor(ServerImpl target) {
		this.target = target;
	}
	
	@Override
	public long getUpTime() {
		return System.currentTimeMillis() - target.startTime;
	}
}
由于MXBean规定,标准MBean也要实现一个接口,其所有向外界公开的方法都要在该接口中声明,否则管理系统就不能从中获取信息。此外,该接口的命名有一定的规范:在标准MBean类名后加上"MBean”后缀。这里的标准MBean类就是ServerMonitor,所以其对应的接口就应该是ServerMonitorMBean。因此ServerMonitorMBean的实现如下:

public interface ServerMonitorMBean {
	public long getUpTime();
}
对于管理系统来讲,这些MBean中公开的方法,最终会被JMX转换为属性(Attribute)、监听(Listener)和调用(Invoke)的概念。下面代码中Main类的manage方法就模拟了管理程序是如何获取监测到的属性,并表现监测结果。

public class Main {
	private static ObjectName objectName;
	private static MBeanServer mBeanServer;
	
	public static void main(String[] args) throws Exception {
		init();
		manage();
	}

	private static void init() throws Exception {
		ServerImpl serverImpl = new ServerImpl();
		ServerMonitor serverMonitor = new ServerMonitor(serverImpl);
		mBeanServer = MBeanServerFactory.createMBeanServer();
		objectName = new ObjectName("objectName:id=ServerMonitor1");
		mBeanServer.registerMBean(serverMonitor, objectName);
	}
	
	private static void manage() throws Exception {
		long upTime = (Long)mBeanServer.getAttribute(objectName, "UpTime");
		System.out.println(upTime);
	}
}

4、JMX API 介绍

4.1 MBeanServer

public ObjectInstance createMBean(String className, ObjectName name);

//创建MBean,并将其注册到MBeanServer中

public ObjectInstance registerMBean(Object object, ObjectName name);

//将Java对象注册到MBeanServer。

public Set queryNames(ObjectName name, QueryExp query);

//根据对象名查找注册的MBean,返回的Set中包含的是查找到的MBean对应的ObjectName.

public Set queryMBeans(ObjectName name, QueryExp query);

//返回的Set中包含的是ObjectInstance对象。

public Attribute getAttribute(ObjectName name, String attributeName);

//返回指定name代表的MBean的名为attributeName的属性

public void setAttribute(ObjectName name, Attribute attr);

//设置属性

public invoke(ObjectName name, String methodName, ..., ...)

//执行指定MBean的指定方法


四、如何怎么使用JMX?

4.1 使用标准MBean方式

例如:如下类时我们的管理目标

public class ControlTarget {
	private long width;
	private long length;
	
	public ControlTarget( long width, long length) {
		this.width = width;
		this.length = length;
	}
	
	public long getWidth() {
		return width;
	}
	
	public long getLength() {
		return length;
	}
}

步骤一:根据需求,创建管理(目标程序)的类,其中包含操纵和获取(目标程序)特性的方法。这个类就是标准MBean类。

public class ControlImpl implements ControlImplMBean {
	private ControlTarget target;
	
	public ControlImpl(ControlTarget target) {
		this.target = target;
	}
	
	@Override
	public long getLength() {
		return target.getLength();
	}
	
	@Override
	public long getWidth() {
		return target.getWidth();
	}
	
	@Override
	public long getArea() {
		return target.getLength() * target.getWidth();
	}
	
	@Override
	public double getLengthWidthRatio() {
		return  target.getLength() * 1.0f / target.getWidth();
	}
}

步骤二:根据标准MBean类抽象出符合规范的MBean类的接口,并修改标准MBean类实现该接口。

public interface ControlImplMBean {
	public long getLength();
	public long getWidth();
	public long getArea();
	public double getLengthWidthRatio();
}

步骤三:创建MBean的代理类,代理中包含创建MBeanServer、生成ObjectName、注册MBean、表现MBean

import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;

import com.sun.jdmk.comm.HtmlAdaptorServer;

public class ControlImplAgent {

	public static void main(String[] args) throws MalformedObjectNameException, NullPointerException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException {
		
		// 创建MBeanServer
		MBeanServer server = MBeanServerFactory.createMBeanServer();
		
		// 为MBean创建ObjectName
		ObjectName controlImplName = new ObjectName("controlImpl:name=firstOne");
		
		// 注册MBean到Server中
		server.registerMBean(new ControlImpl(new ControlTarget(50, 200)), controlImplName);
		
		// 表现MBean(一种方式)
		ObjectName adapterName = new ObjectName("ControlImpl:name=htmladapter,port=8082");
		HtmlAdaptorServer adapter = new HtmlAdaptorServer();
		server.registerMBean(adapter, adapterName);
		
		adapter.start();
		//adapter.stop();
	}

}

运行ControlImplAgent类,然后在浏览器地址栏输入:http://localhost:8082,就会显示如下页面:


点击name=firstOne链接,会显示如下页面:


至此,我们看到了我们管理目标的属性,因此一个简单的管理程序功能就实现了。


参考:http://www.ibm.com/developerworks/cn/java/j-lo-jse63/

参考:http://blog.csdn.net/javafreely/article/details/9237799


  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值