JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架。JMX是一套标准的代理和服务,主要用于对JAVA应用程序和JVM进行监控和管理。
JConsole和JVisualVM中能够监控到JAVA应用程序和JVM的相关信息都是通过JMX实现的。

分布层:是JMX架构对外一层,分布层负责使用JMX代理对外部世界可用。有两种类型的分布式交互。第一种类型是由适配器来实现,它通过HTTP或SNMP一类的协议提供了MBean的可见性。第二种类型是连接器,它将代理的API暴露给其它分布式技术,如Java RMI。(管理访问框架接口)
代理层:代理层主要组件是MBean服务器,MBean服务器提供MBean的注册使用,它是JMX代理的核心。(访问资源接口)
指令层:指令层是接近管理资源的一层,它由代理中注册的MBean构成MBean使得资源可以通过代理来被管理。(处理资源)
package test;

/**
 * MBean中各方法的参数和返回值的类型做严格限制,
 * 这些类型只能是基本类型(String,int,double,float...)
 * 以及JMX规范指定的CompositeDataSupport(用于组合基本类型)
 */
public class Hello implements HelloMBean {
    public void sayHello() {
        System.out.println("hello, world");
    }

    public int add(int x, int y) {
        System.out.println("add done "+x+"  "+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;
}
package test;

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

public class HelloListener implements NotificationListener {

    public void handleNotification(Notification notification, Object handback) {
        if (handback instanceof Hello) {
            Hello hello = (Hello) handback;
            hello.add(Integer.parseInt(notification.getMessage()), 1);
        }
    }

}
package test;

/**
 * 接口名必须以MBean结尾
 */
public interface HelloMBean {

    public void sayHello();
    public int add(int x, int y);

    public String getName();

    public int getCacheSize();
    public void setCacheSize(int size);
}
package test;

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

public class Jack extends NotificationBroadcasterSupport implements JackMBean {
    private int seq = 0;

    public void say(int a) {
        //创建一个信息包
        Notification notify =
                //通知名称;谁发起的通知;序列号;发起通知时间;发送的消息
                new Notification("jack.hi", this, ++seq, System.currentTimeMillis(), a+"");
        sendNotification(notify);
    }
}
package test;

public interface JackMBean {
    void say(int a);
}
package test;

import javax.management.MBeanInfo;
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;

/*
  ClassLoadingMXBean Java 虚拟机的类加载系统。
  CompilationMXBean Java 虚拟机的编译系统。
  MemoryMXBean Java 虚拟机的内存系统。
  ThreadMXBean Java 虚拟机的线程系统。
  RuntimeMXBean Java 虚拟机的运行时系统。
  OperatingSystemMXBean Java 虚拟机在其上运行的操作系统。
  GarbageCollectorMXBean Java 虚拟机中的垃圾回收器。
  MemoryManagerMXBean Java 虚拟机中的内存管理器。
  MemoryPoolMXBean Java 虚拟机中的内存池。
 */
public class JMXClient {
    public static void main(String[] args) throws Exception {
        JMXServiceURL url =
                new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:9999/jmxrmi");
        JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
        MBeanServerConnection conn = jmxc.getMBeanServerConnection();
        String[] domains = conn.getDomains();
        for (String domain : domains) {
            // System.out.println(domain);
        }
        ObjectName name = new ObjectName("test:type=Hello");
        MBeanInfo mBeanInfo = conn.getMBeanInfo(name);
        // 获取mbean信息
        System.out.println(mBeanInfo.toString());
        // 获取属性
        Object o = conn.getAttribute(name, "CacheSize");
        System.out.println(o);
        Object o2 = conn.getAttribute(name, "Name");
        System.out.println(o2);
        HelloMBean helloMBean = MBeanServerInvocationHandler.newProxyInstance(conn, name, HelloMBean.class, true);
        // 调用方法
        helloMBean.sayHello();
        // 设置值
        helloMBean.setCacheSize(100);
        ObjectName name2 = new ObjectName("test:type=Jack");
        JackMBean jackMBean = MBeanServerInvocationHandler.newProxyInstance(conn, name2,
                JackMBean.class, true);
        jackMBean.say(2);
        // 获取jvm自带的
        ObjectName o3 = new ObjectName("java.lang:type=ClassLoading");
        MBeanInfo  mBeanInfo1 = conn.getMBeanInfo(o3);
        Object TotalLoadedClassCount = conn.getAttribute(o3,"TotalLoadedClassCount");
        System.out.println(mBeanInfo1);
        System.out.println(TotalLoadedClassCount);
    }
}
package test;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;

/**
 * 如果要远程访问,被访问 Mbean 服务器首选需要 命令行选项启动远程虚拟机,这些选项设置虚拟机的相关 JMX 代理侦听请求的端口,以及起作用的安全级别如下:
 * -Dcom.sun.management.jmxremote.port=9999 -- 指定端口
 * -Dcom.sun.management.jmxremote.authenticate=false – 指定是否需要密码验证
 * -Dcom.sun.management.jmxremote.ssl=false – 指定是否使用 SSL 通讯
 */
public class JMXServer {
    public static void main(String[] args) throws Exception {
        /**
         * 1、 通过工厂类获取Mbean Server,用来做Mbean的容器
         * 2、 ObjectName的取名规范:域名:name=Mbean名称,其中域名和Mbean的名称可以任取。这样定义后,我们可以唯一标示我们定义的这个Mbean的实现类了
         * 3、最后将Hello这个类注册到MbeanServer中,注入需要创建一个ObjectName类
         */
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        ObjectName name = new ObjectName("test:type=Hello");
        Hello mbean = new Hello();
        mbs.registerMBean(mbean, name);
        ObjectName name2 = new ObjectName("test:type=Jack");
        Jack jack = new Jack();
        // 设置通知
        jack.addNotificationListener(new HelloListener(),null,mbean);
        mbs.registerMBean(jack, name2);
        System.out.println("Waiting forever...");
        Thread.sleep(Long.MAX_VALUE);
    }
}

v4ki5mqu
1 声望0 粉丝

« 上一篇
类卸载
下一篇 »
动态代理