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);
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。