JMX实例

JMX致力于解决分布式系统管理的问题,与web service类似

JMX基本构架:
JMX分为三层,分别负责处理不同的事务。它们分别是:

    Instrumentation 层:
        Instrumentation层主要包括了一系列的接口定义和描述如何开发MBean的规范。
        通常JMX所管理的资源有一个或多个MBean组成,因此这个资源可以是任何由Java语言开发的组件,
        或是一个JavaWrapper包装的其他语言开发的资源。

    Agent 层:
        Agent 用来管理相应的资源,并且为远端用户提供访问的接口。
        Agent层构建在Intrumentation层之上,并且使用并管理 Instrumentation层内部描述的组件。
        通常Agent由一个MBeanServer和多个系统服务组成。
        另外Agent还提供一个或多个 Adapter或Connector以供外界的访问。
        JMX Agent并不关心它所管理的资源是什么。

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

JMX术语:

    MBean:
         是Managed Bean的简称。在JMX中MBean代表一个被管理的资源实例。

         通过MBean中暴露的方法和属性,外界可以获取被管理的资源的状态和操纵MBean的行为。

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


    MBeanServer:
         MBean生存在一个MBeanServer中。MBeanServer管理这些MBean,并且代理外界对它们的访问。

         MBeanServer提供了一种注册机制,是的外界可以通过名字来得到相应的MBean实例。


    JMX Agent:
         Agent只是一个Java进程,它包括这个MBeanServer和一系列附加的MbeanService。

         当然这些Service也是通过MBean的形式来发布。


    Protocol Adapters and Connectors
         JMX Agent通过各种各样的Adapter和Connector来与外界(JVM之外)进行通信。
         同样外界(JVM之外)也必须通过某个Adapter和Connector来向JMX Agent发送管理或控制请求。
         Adapter 和Connector的区别在于:Adapter是使用某种Internet协议来与JMX Agent获得联系。
         Agent端会有一个对象 (Adapter)来处理有关协议的细节。

         JMX Agent可以带有任意多个Adapter,因此可以使用多种不同的方式访问Agent。


下面是实例


HelloBean.java // 接口

package com.sscc.jmx;

public interface HelloMBean {
      public String getName();
      public void setName(String name);
      public void printHello();
      public void printHello(String whoName);
}

Hello.java  // 实现类(标准MBean)

package com.sscc.jmx;

import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;

/* Standard MBean */
public class Hello extends NotificationBroadcasterSupport implements HelloMBean    {

	private String name;
	
	private boolean writable;
	
	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return name;
	}

	@Override
	public void setName(String name) {
		// TODO Auto-generated method stub
		this.name = name;
	}

	public boolean isWritable() {
		return writable;
	}

	public void setWritable(boolean writable) {
		this.writable = writable;
	}
	
	@Override
	public void printHello() {
	    final Notification notification = new Notification("com.sscc.jmx.hello", this, -1, 
	    System.currentTimeMillis(), "printHello is called"); 
	    sendNotification(notification); 
		// TODO Auto-generated method stub
		System.out.println("Hello World");
	}

	@Override
	public void printHello(String whoName) {
	    final Notification notification = new Notification("com.sscc.jmx.hello", this, -1, 
	    System.currentTimeMillis(), "printHello with name is called"); 
	    sendNotification(notification); 
		// TODO Auto-generated method stub
		System.out.println("Hello!" + whoName);
	}
}

HelloListener.java // 监听类

package com.sscc.jmx;

import javax.management.Notification;
import javax.management.NotificationListener;

public class HelloListener  implements NotificationListener  {

	public void handleNotification(Notification notification, Object o) { 
	    System.out.println(this.getClass().getName() + 
	              " Notification Listener --" + notification.getMessage()); 
	}
}

ModelMBeanUtils.java //实现类(模型MBean)

package com.sscc.jmx;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import javax.management.modelmbean.ModelMBeanAttributeInfo;
import javax.management.modelmbean.ModelMBeanConstructorInfo;
import javax.management.modelmbean.ModelMBeanInfo;
import javax.management.modelmbean.ModelMBeanInfoSupport;
import javax.management.modelmbean.ModelMBeanOperationInfo;
import javax.management.modelmbean.RequiredModelMBean;

public class ModelMBeanUtils {
	    
    public RequiredModelMBean createModlerMBean(@SuppressWarnings("rawtypes") Class cls) {
        RequiredModelMBean model = null;
        try {
            model = new RequiredModelMBean();
            model.setManagedResource(new Hello(), "ObjectReference");
            ModelMBeanInfo info = createModelInfo(cls);
            model.setModelMBeanInfo(info);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return model;
    }
    
    @SuppressWarnings("unchecked")
	public Method getGetMethodName(@SuppressWarnings("rawtypes") Class cls, Field prop) {
    	if (prop == null) {
    		return null;
    	}
    	
    	String methodName;
    	if (prop.getType().equals(Boolean.class) || prop.getType().equals(boolean.class)) {
    		methodName = "is" + prop.getName().substring(0,1).toUpperCase() + prop.getName().substring(1);
    	} else {
    		methodName = "get" + prop.getName().substring(0,1).toUpperCase() + prop.getName().substring(1);
    	}
    	
    	try {
    	    return cls.getMethod(methodName, (Class[])null);
    	} catch (Exception e) {
    	}
    	return null;
    }
    
    @SuppressWarnings("unchecked")
	public Method getSetMethodName(@SuppressWarnings("rawtypes") Class cls, Field prop) {
    	if (prop == null) {
    		return null;
    	}
    	
    	String methodName = "set" + prop.getName().substring(0,1).toUpperCase() + prop.getName().substring(1);
    	
    	try {
    	    return cls.getMethod(methodName, prop.getType());
    	} catch (Exception e) {
    	}
    	return null;
    }
   
	private ModelMBeanInfo createModelInfo(@SuppressWarnings("rawtypes") Class cls) throws Exception {
    	Field[] fields = cls.getDeclaredFields();
    	Method getMethod = null;
    	Method setMethod = null;
    	
    	ModelMBeanAttributeInfo[] nameAttrInfo = new ModelMBeanAttributeInfo[fields.length];
    	for(int i = 0;i<= fields.length - 1; i++) {
    		getMethod = getGetMethodName(cls, fields[i]);
    		setMethod = getSetMethodName(cls, fields[i]);
    		
            nameAttrInfo[i] = new ModelMBeanAttributeInfo(
            		fields[i].getName(),
            		"field description",
            		getMethod,setMethod,
                    null
            );
    	}
    	
    	@SuppressWarnings("rawtypes")
		Constructor[] Constructors = cls.getDeclaredConstructors();
    	ModelMBeanConstructorInfo[] print1Info = new ModelMBeanConstructorInfo[Constructors.length];
    	for(int i = 0;i<= Constructors.length - 1; i++) {
    		
    		print1Info[i] = new ModelMBeanConstructorInfo(
            		"Constructors description",
            		Constructors[i]
            );
    	}
    	
		Method[] methods = cls.getMethods();
    	ModelMBeanOperationInfo[] print2Info = new ModelMBeanOperationInfo[methods.length];
    	for(int i = 0;i<= methods.length - 1; i++) {
    		print2Info[i] = new ModelMBeanOperationInfo(
            		"Constructors description",
            		methods[i]
            );
    	}
    	
        // create ModelMBeanInfo        
        ModelMBeanInfo mbeanInfo = new ModelMBeanInfoSupport(//
                RequiredModelMBean.class.getName(), // MBean Name
                "class description",                // description      
                nameAttrInfo,                       // Properties
                print1Info,                         // Constructors   
                print2Info,                         // Methods   
                null,                               // ModelMBeanNotificationInfo
                null                                // MBean description
        );
        return mbeanInfo;
    	
    }
}

HtmlServerAgent.java  // Adapter类

package com.sscc.jmx;

import javax.management.MBeanServer;
import javax.management.ObjectName;

import com.sun.jdmk.comm.HtmlAdaptorServer;

public class HtmlServerAgent implements Agent {
	private int connectorPort = 8082;
	public int getConnectorPort() {
		return connectorPort;
	}

	public void setConnectorPort(int connectorPort) {
		this.connectorPort = connectorPort;
	}

	private MBeanServer mBeanServer;
	private HtmlAdaptorServer htmlAdaptorServer;
	
	// constructor
	public HtmlServerAgent(MBeanServer mBeanServer) {
		this.mBeanServer = mBeanServer;
	}
	
	// Start HtmlAdaptorServer
	public void StartServer() throws Exception {
		this.htmlAdaptorServer = new HtmlAdaptorServer();
		ObjectName hasName = new ObjectName("DefaultDomain:name=HTMLAdaptor");
	    htmlAdaptorServer.setPort(connectorPort);
	    mBeanServer.registerMBean(htmlAdaptorServer, hasName );
	    htmlAdaptorServer.start();
	    System.out.println("HTMLAdaptorServer start");
	}
}

JMXConnectorServerAgent.java  // Connector

package com.sscc.jmx;

import javax.management.Attribute;
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 JMXConnectorServerAgent implements Agent {
	private int connectorPort = 1099;
	public int getConnectorPort() {
		return connectorPort;
	}

	public void setConnectorPort(int connectorPort) {
		this.connectorPort = connectorPort;
	}

	private MBeanServer mBeanServer;
	
	// constructor
	public JMXConnectorServerAgent(MBeanServer mBeanServer) {
		this.mBeanServer = mBeanServer;
	}
	
	// Start HtmlAdaptorServer
	public void StartServer() throws Exception {
        // NamingService MBean
        ObjectName namingName = ObjectName.getInstance("naming:type=rmiregistry");
        mBeanServer.registerMBean(Class.forName("mx4j.tools.naming.NamingService").newInstance(), namingName);
        
        Attribute attr = new Attribute("Port", Integer.valueOf(connectorPort));
        mBeanServer.setAttribute(namingName, attr);
        
        // Start NamingService
        try {
        	mBeanServer.invoke(namingName, "start", null, null);
        } catch (Exception e) {
        }
        
        // JMXServiceURL
        JMXServiceURL jmxUrl;
    
        // JMXConnectorServer
        int namingPort = ((Integer)mBeanServer.getAttribute(namingName, "Port")).intValue();

        // 2. jndiPath
        String jndiPath = "/jmxconnector";
        // 3. JMXServiceURL
        jmxUrl = new JMXServiceURL("service:jmx:rmi://localhost/jndi/rmi://localhost:"
                                        + namingPort + jndiPath);
   
        // 4.Create and start the RMIConnectorServer
        JMXConnectorServer connectorServer = JMXConnectorServerFactory
                                .newJMXConnectorServer(jmxUrl, null, mBeanServer);
        
        connectorServer.start();
	    System.out.println("JMXConnectorServer start");
	}
}

Server.java   // server端的主程序

package com.sscc.jmx;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.management.modelmbean.RequiredModelMBean;

public class Server {
	
	private MBeanServer mBeanServer;
    
	public MBeanServer getmBeanServer() {
		return mBeanServer;
	}

	public void setmBeanServer(MBeanServer mBeanServer) {
		this.mBeanServer = mBeanServer;
	}

	public Server() {
	    //server = ManagementFactory.getPlatformMBeanServer();
	    mBeanServer = MBeanServerFactory.createMBeanServer();
	}
	
	public void startAgent(Agent agent) throws Exception {
		agent.StartServer();
	}
	
	public void addBean(Object object, ObjectName objectName) throws Exception {
		mBeanServer.registerMBean(object, objectName);
	}
	
	public static void main(String[] args) {

		try {
			Server server = new Server();
			HelloMBean hello = new Hello();
			HelloListener helloListener = new HelloListener();
			((Hello)hello).addNotificationListener(helloListener, null, null);
			
	                ObjectName helloName = new ObjectName("thisDomain:name=hello");
			server.addBean(hello, helloName);
			
			ModelMBeanUtils modelMBeanUtils = new ModelMBeanUtils();
			RequiredModelMBean requiredModelMBean = modelMBeanUtils.createModlerMBean(Hello.class);
	                ObjectName helloModelName = new ObjectName("thisDomain:name=helloModel");
	                server.addBean(requiredModelMBean, helloModelName);
	        
			// HtmlServerAgent start
			Agent agent1 = new HtmlServerAgent(server.getmBeanServer());
			server.startAgent(agent1);

			// JMXConnectorServerAgent start
			Agent agent2 = new JMXConnectorServerAgent(server.getmBeanServer());
			server.startAgent(agent2);

		} catch (Exception e) {
		    e.printStackTrace();
		}
	}
}

HelloClient.java //客户端调用

package com.sscc.jmx;

import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class HelloClient {
	
    private JMXServiceURL jmxUrl;
	private JMXConnector connector;
	private MBeanServerConnection mBeanServerconnection;

	public HelloClient() throws Exception{
	    createJMXRmiConnector();
	    createMBeanServerConnection();
	}
	    
	private void createJMXRmiConnector() throws Exception{
	    // 1.The JMXConnectorServer protocol
	    String serverProtocol = "rmi";

	    // 2.The RMI server's host
	    // this is actually ignored by JSR 160
	    String serverHost = "localhost";

	    // 3.The host, port and path where the rmiregistry runs.
	    String namingHost = "localhost";
	    int namingPort = 1099;
	    String jndiPath = "/jmxconnector";

	    // 4. connector server url
	    jmxUrl = new JMXServiceURL("service:jmx:" +
	                 serverProtocol + "://" + serverHost +
	                 "/jndi/rmi://" + namingHost + ":" +
	                 namingPort + jndiPath);
	        
	    // Connect a JSR 160 JMXConnector to the server side
	    connector = JMXConnectorFactory.connect(jmxUrl);
    }
		 
    private void createMBeanServerConnection() throws Exception{
	mBeanServerconnection = connector.getMBeanServerConnection();
    }
		 
	public void test()throws Exception{
			   
	    ObjectName  oName = new ObjectName("thisDomain", "name", "hello");
	    // 获取代理对象
	    Object proxy = MBeanServerInvocationHandler
		         .newProxyInstance(mBeanServerconnection,oName, HelloMBean.class, true);

	    HelloMBean helloMBean = (HelloMBean)proxy;
	    helloMBean.setName("myname");
	    helloMBean.printHello();
	    helloMBean.printHello("haha");
		
		// 直接调用
	    ObjectName  modelName = new ObjectName("thisDomain", "name", "helloModel");
		mBeanServerconnection.invoke(modelName, "printHello", null, null);
	}

	public static void main(String[] args) throws Exception {
	    HelloClient hc = new HelloClient();
	    hc.test();
	}
}

执行Server.java的main方法,启动服务。

然后可以去通过浏览器  http://localhost:8082  调用Mbean的方法。

也可以执行HelloClient.java的main, 通过客户端程序调用MBean。

以上程序需要的jar

    jmxremote_optional.jar
    jmxremote.jar
    jmxri.jar
    jmxtools.jar
    mx4j-tools.jar
    naming-management-0.8.jar
    rmissl.jar
    org.apache.commons.lang_2.6.0.v201205030909.jar













  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值