JMX
MBean:是Managed Bean的简称,可以翻译为“管理构件”。在JMX中MBean代表一个被管理的资源实例,通过MBean中暴露的方法和属性,外界可以获取被管理的资源的状态和操纵MBean的行为。事实上,MBean就是一个Java Object,同JavaBean模型一样,外界使用自醒和反射来获取Object的值和调用Object的方法,只是MBean更为复杂和高级一些。MBean通过公共方法以及遵从特定的设计模式封装了属性和操作,以便暴露给管理应用程序。例如,一个只读属性在管理构件中只有Get方法,既有Get又有Set方法表示是一个可读写的属性。一共有四种类型的MBean: Standard MBean, Dynamic MBean, Open MBean, Model MBean。
MBeanServer:MBean生存在一个MBeanServer中。MBeanServer管理这些MBean,并且代理外界对它们的访问。并且MBeanServer提供了一种注册机制,是的外界可以通过名字来得到相应的MBean实例。
JAVA自带的MBean
当我们在用jconsole、jvisualvm进行监控java进程时,通常都能看到cpu、内存、线程、垃圾收集等使用情况,其实数据都是通过jmx从jvm提供的一些mbean里面取的。
JAVA自带的MBean如下
- ClassLoadingMXBean
ClassLoadMXBean 包括一些类的装载信息,比如有多少类已经装载 / 卸载(unloaded),虚拟机类装载的 verbose 选项(即命令行中的 Java – verbose:class 选项)是否打开,还可以帮助用户打开 / 关闭该选项。 - CompilationMXBean
CompilationMXBean 帮助用户了解当前的编译器和编译情况,该 mxbean 提供的信息不多。 - GarbageCollectorMXBean
相对于开放人员对 GC 的关注程度来说,该 mxbean 提供的信息十分有限,仅仅提供了 GC 的次数和 GC 花费总时间的近似值。但是这个包中还提供了三个的内存管理检测类:MemoryManagerMXBean,MemoryMXBean 和 MemoryPoolMXBean。MemoryManagerMXBean这个类相对简单,提供了内存管理类和内存池(memory pool)的名字信息。MemoryMXBean这个类提供了整个虚拟机中内存的使用情况,包括 Java 堆(heap)和非 Java 堆所占用的内存,提供当前等待 finalize 的对象数量,它甚至可以做 gc(实际上是调用 System.gc)。
MemoryPoolMXBean该信息提供了大量的信息。在 JVM 中,可能有几个内存池,因此有对应的内存池信息,因此,在工厂类中,getMemoryPoolMXBean() 得到是一个 MemoryPoolMXBean 的 list。每一个 MemoryPoolMXBean 都包含了该内存池的详细信息,如是否可用、当前已使用内存 / 最大使用内存值、以及设置最大内存值等等。 - OperatingSystemMXBean
该类提供的是操作系统的简单信息,如构架名称、当前 CPU 数、最近系统负载等。 - RuntimeMXBean
运行时信息包括当前虚拟机的名称、提供商、版本号,以及 classpath、bootclasspath 和系统参数等等。 - ThreadMXBean
在 Java 这个多线程的系统中,对线程的监控是相当重要的。ThreadMXBean 就是起到这个作用。ThreadMXBean 可以提供的信息包括各个线程的各种状态,CPU 占用情况,以及整个系统中的线程状况。从 ThreadMXBean 可以得到某一个线程的 ThreadInfo 对象。这个对象中则包含了这个线程的所有信息。
JMX的简单使用
首先定义一个MBean接口
public interface HelloWorldMBean {
String getGreeting();
void setGreeting(String greeting);
void printGreeting();
}
然后写一个MBean
public class HelloWorld implements HelloWorldMBean {
private String greeting;
public HelloWorld(String greeting) {
this.greeting = greeting;
}
public HelloWorld() {
this.greeting = "hello world!";
}
public String getGreeting() {
return greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
public void printGreeting() {
System.out.println(greeting);
}
}
创建agent,其持有一个MBeanServer
public class HelloAgent implements NotificationListener {
private MBeanServer mbs;
public HelloAgent() {
this.mbs = MBeanServerFactory.createMBeanServer("HelloAgent");
HelloWorld hw = new HelloWorld();
ObjectName helloWorldName = null;
try{
helloWorldName = new ObjectName("HelloAgent:name=helloWorld");
mbs.registerMBean(hw, helloWorldName);
} catch (Exception e) {
e.printStackTrace();
}
startHtmlAdaptorServer();
}
public void startHtmlAdaptorServer(){
HtmlAdaptorServer htmlAdaptorServer = new HtmlAdaptorServer();
ObjectName adapterName = null;
try {
// 多个属性使用,分隔
adapterName = new ObjectName("HelloAgent:name=htmladapter,port=9092");
htmlAdaptorServer.setPort(9092);
mbs.registerMBean(htmlAdaptorServer, adapterName);
htmlAdaptorServer.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]){
System.out.println(" hello agent is running");
HelloAgent agent = new HelloAgent();
}
}