JMX监控(MBean)

时间:2024-03-26 21:04:26
一、引言 写道
随着企业 IT 规模的不断增长,IT 资源(IT resource)数量不断增加,IT 资源的分布也越来越分散。可以想象,甚至对于一家只有几百台 PC 公司的 IT 管理人员来说,分发一个安全补丁并且保证其在每台 PC 上的安装,如果只依赖人工来完成那简直就是一场噩梦。这样,IT 管理系统就应运而生。
JMX可以监控与管理系统资源,一般小公司不注重IT资源监控,而大公司非常得视。目前JSE支持JMX接口规范,如Tomcat源码采用大量JMX Mbean监控资源。

 

写道
MX 使用了 Java Bean 模式来传递信息。一般说来,JMX 使用有名的 MBean,其内部包含了数据信息,这些信息可能是:应用程序配置信息、模块信息、系统信息、统计信息等。另外,MBean 也可以设立可读写的属性、直接操作某些函数甚至启动 MBean 可发送的 notification 等。
JMX 规范可以分为三层: 设备层, 代理层, 分布式服务层。 设备层规范定义了编写可由 JMX 管理的资源的标准,即如何写 MBean; 代理曾规范定义了创建代理的规范,封装了 MBean Server;分布式服务层主要定义了对代理层进行操作的管理接口和构件。
javax.management.MBeanServer实现了 Agent 的功能,以标准的方式给出了管理系统访问 JMX 框架的接口。而 javax.management.MBeans实现了以标准的方式给出了 JMX 框架访问资源的接口。而从类库的层次上看,JMX 包括了核心类库 java.lang.management和 javax.management包。java.lang.management包提供了基本的 VM 监控功能,而 javax.management包则向用户提供了扩展功能。

JMX监控(MBean)

 

写道
要使一个 Java 对象可管理,则必须创建相应的 MBean 对象,并通过这些 MBean 对象管理相应的 Java 对象。当拥有 MBean 类后,需要将其实例化并注册到 MBeanServer 上。
一共有四种类型的 MBean , 分别是标准类型 MBean, 动态类型 MBean, 开放类型 MBean 和模型类型 MBean
1)标准MBeans(Standard MBeans)设计和实现是最简单的,这类MBean使用自己的方法名作为管理接口;——在前一篇中的Hello、HelloMBean就是一个标准MBeans(Standard MBeans)
2)动态MBeans(Dynamic MBeans)必须实现一个指定的接口,由于动态MBeans在运行期间暴露它们的管理接口,因此更为灵活;
3)开放MBeans(Open MBeans)属于动态MBeans,这类MBean依靠基础数据类型来实现通用管理,并为友情用户进行自我声明;
4)模型MBeans(Model MBeans)同样也是动态MBeans,这类MBeans是完全可配置的,在运行期间进行自我声明;它们为资源动态工具提供一个一般性的,有默认行为的MBeans类。

   

了解一下ObjectName对象 写道
domain(域)下的一些属性,属性的存储采取key-value的方式来存储,这个类的一个精华所在就是domian及属性(key或者value)都是支持正则的,比如:*表示匹配所有,?表示匹配一个字符。
格式如下:
domain: key1 = value1 , key2 = value2
一般实例化ObjectName都传入域(domain),key,value
1) ObjectName.getInstance("domain:key1=value1")
2) ObjectName.getInstance("domain", "key1", "value1")
3) ObjectName.getInstance("domain", hashtable)
也可以直接调用构造法实例化,如 ObjectName objectName = new ObjectName("domain:key1=value1")
下面将Mbean注到MBeanServer需要用到ObjectName,所以提前了解一下。

 

public static ObjectName getInstance(ObjectName name)
	    throws NullPointerException {
	if (name.getClass().equals(ObjectName.class))
	    return name;
	try {
	    return new ObjectName(name.getSerializedNameString());
	} catch (MalformedObjectNameException e) {
	    throw new IllegalArgumentException("Unexpected: " + e);
	    // can't happen
	}
    }
  public static ObjectName getInstance(String domain,
					 Hashtable<String,String> table)
	throws MalformedObjectNameException, NullPointerException {
        return new ObjectName(domain, table);
    } 

public ObjectName(String domain, String key, String value)
	throws MalformedObjectNameException, NullPointerException {
	// If key or value are null a NullPointerException
	// will be thrown by the put method in Hashtable.
	//
	Map<String,String> table = Collections.singletonMap(key, value);
	construct(domain, table);
 }

 

二、MBean 类型 写道
依次描述MBean各种类型标准MBeans、动态MBeans、模型MBeans

 

2.1 标准 MBean 写道
标准 MBean 是最简单的一类 MBean,与动态 Bean 不同,它并不实现 javax.management包中的特殊的接口。说它是标准 MBean, 是因为其向外部公开其接口的方法和普通的 Java Bean 相同,是通过 lexical,或者说 coding convention 进行的,代码实现如下:

 

/**
* 与普通接口定义一样
*/
public interface HelloMBean { 
    public void sayHello(); 
    public int add(int x, int y);  
    public String getName();     
    public int getCacheSize(); 
    public void setCacheSize(int size); 
} 

 

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; 
}

 

public class ITAgentMain { 
 
    public static void main(String[] args) throws Exception { 
        // MBeanServer对象获取
        // 或采用MBeanServerFactory.createMBeanServer()获取MBeanServer对象
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 
        // 构建ObjectName
        ObjectName name = new ObjectName("com.example:type=Hello"); 
        Hello mbean = new HelloMBean (); 
        // 将Mbean注册到MBeanServer 
        mbs.registerMBean(mbean, name); 
        //创建一个AdaptorServer,这个类将决定MBean的管理界面,这里用最普通的Html型界面。AdaptorServer其实也是一个MBean。  
        // alpha:name=HelloWorld的名字是有一定规则的,格式为:“域名:name=MBean名称”,域名和MBean名称都可以任意取。  
        ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082"); //     
         HtmlAdaptorServer adapter = new HtmlAdaptorServer();     
         server.registerMBean(adapter, adapterName);     
         adapter.start();     
         System.out.println("start.....");  
    } 
} 

 

JMX注册服务端口 写道
需要注册一个端口,绑定url后,客户端就可以使用rmi通过url方式来连接JMXConnectorServer,就可以远程监控资源,目很多开源软件都支持如Apache activeMQ可以用JDK 自带的jconsole监控对列、主题资源。
这里的8888(默认为1099)是通讯端口或者查找端口,服务端在createRegistry时实际上会new ServerSocket(8888),客户端的socket通过与端口号为8888的服务端端口互联lookup到server对象。客户端获取到的server对象在和服务端的sketon对象进行通讯时实际上也会建立socket连接,数据传输时的ServerSocket也需要一个端口(不同于通讯端口),称之为数据端口。

 

//JMXConnectorServer service 
		try {
			//这句话非常重要,不能缺少!注册一个端口,绑定url后,客户端就可以使用rmi通过url方式来连接JMXConnectorServer
			LocateRegistry.createRegistry(8888);
			JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8888/server");
                        // 注意:server为MBeanServer对象(Mbean注册到此对象)
			JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server);
			System.out.println("....................begin rmi start.....");
			cs.start();
			System.out.println("....................rmi start....."); 
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 

 

     动态Mbeans、模型Mbeans(apache 开源实现)待续.....