当前位置 : 首页 » 文章分类 :  开发  »  Java-JMX

Java-JMX

[TOC]


概述

JMX(Java Management Extensions,即Java管理扩展)是一个为应用程序、设备、系统等植入管理功能的框架。
JMX可以跨越一系列异构操作系统平台、系统体系结构和网络传输协议,灵活的开发无缝集成的系统、网络和服务管理应用。

JMX分层结构

  • 设备层(Instrumentation Level):设备层的主要任务就是对资源进行封装,使之成为可管理资源。所谓封装,就是通过将资源用类似Java Bean的方式描述出来。当资源以这种方式被封装成为可管理资源后,就被称作MBean(Management Bean)。
  • 代理层(Agent Level):代理层位于装配层和分布式服务层之间,包含 MBean服务器,代理服务,连接器和协议适配器。代理层的作用体现在内外两方面:对内它通过MBean服务器(Managed Bean Server)维护着MBean的生命周期(包括注册和注销MBean),同时为所注册的MBean提供各类服务;对外通过连接器和协议适配器将已注册的MBean的管理接口暴露给外面的管理应用使用。
  • 分布式服务层(Distributed Service Level):分布式服务层驻留着管理应用。管理应用通过连接器(Connector)与MBean服务器建立连接,并通过管理接口(Management Interface)去访问各个Mbean所包装的可管理资源。

MBean

MBean是Management Bean的缩写,负责将可管理资源和服务封装成类似Java Bean的形式。通过MBean的特性可以访问可管理资源的各类信息。MBean对资源的封装体现在以下几个方面:

  • 1.必须是公用的,非抽象的类
  • 2.必须有至少一个公用的构造器
  • 3.必须实现它自己的相应的MBean接口或者实现javax.management.DynamicMBean接口
  • 4.可选的,一个MBean可以实现javax.management.NotificationBroadcaster接口MBean的类型

要使一个 Java 对象可管理,则必须创建相应的 MBean 对象,并通过这些 MBean 对象管理相应的 Java 对象。当拥有 MBean 类后,需要将其实例化并注册到 MBeanServer 上。

四种MBean类型

有四种类型的MBean:

  • 1.标准MBeans(Standard MBeans)设计和实现是最简单的,这类MBean使用自己的方法名作为管理接口;
  • 2.动态MBeans(Dynamic MBeans)动态MBean适用于描述那些要在运行时才可确切知道的数据结构的资源。与标准 MBean不同的是,动态MBean所暴露的管理接口不必事先确定,而是可根据运行时的情况,判断生成最终的管理接口。比如用以描述配置的MBean,可能需要通过对配置文件的分析来最终获得属性的名称和类型。
  • 3.开放MBeans(Open MBeans)属于动态MBeans,这类MBean依靠基础数据类型来实现通用管理,Open MBean是一类特殊的动态Mbean,它的特征是只针对特定对象,比如原始的数据类型(如int和float)和复合的数据类型。
  • 4.模型MBeans(Model MBeans)同样也是动态MBeans,这类MBeans是完全可配置的,在运行期间进行自我声明;与标准和动态MBean相比,你可以不用写MBean类,只需使用javax.management.modelmbean.RequiredModelMBean即可。

标准MBean实例

标准 MBean 是最简单的 MBean 类型。通过标准 MBean 来管理一个 Java 对象需要以下步骤:

  1. 创建一个接口,命名规范为:Java类名 + MBean。如Java类为Hello,则需要创建HelloMBean接口。
  2. 创建Java类,使它实现刚创建的接口,命名规则为类名+MBean必须等于接口名。
  3. 获取MBeanServer
  4. 创建一个ObjectName来设定MBean的名称(name=MBean名)
  5. 然后将 MBean 注册到 MBeanServer。

定义HelloMBean接口

package com.masi.jmx.standard;

//接口名必须以MBean结尾
public interface HelloMBean {
    public String getName();
    public void setName(String name);
    public void printHello();
}

实现HelloMBean接口

package com.masi.jmx.standard;

//类名必须和接口MBean前的内容相同,即类名+MBean必须等于接口名
public class Hello implements HelloMBean {
    String name;
    @Override
    public void printHello() {
        System.out.println("你好,"+name);
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

}

将MBean注册到MBeanServer

package com.masi.jmx.standard;

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

public class StandardMBeanMain {
    public static void main(String[] args) throws Exception{
        MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
        mBeanServer.registerMBean(new Hello(), new ObjectName("MBeanTest:name=StandardMBean"));
        Thread.sleep(60*60*1000);
    }
}

Run As->Java Application 启动,然后用JConsole连接测试。


模型MBean


参考


JMX连接器

  • RMI Connector:JMX API定义了一个标准连接器 RMI Connector,它支持通过RMI协议远程访问一个MBeanServer
  • JMXMP Connector:JMX API定义了一个可选的连接器 JMXMP Connector,它实现了JMXMP协议(JMX Message Protocol)。作为一个可选连接器,它不集成在JavaSE平台中,若需要从Sun官方下载jar
  • 用户可自定义连接器协议

参考


JMX与Spring集成

Spring与JMX集成,实现方式灵活而且简单,主要体现在:

  • 可以自动探测实现MBean接口的MBean对象,而且可以将一个普通的Spring Bean注册为MBean;
  • 定制管理MBean的接口,根据需要暴露特定管理MBean的操作;
  • 使用注解定义MBean管理接口;
  • 可以实现对本地和远程MBean的代理。

利用Spring注册标准MBean

Spring提供的类org.springframework.jmx.export.MBeanExporter可自动探测实现MBean接口的MBean对象

标准MBean接口及实现类

HelloMBean接口:

package com.masi.jmx.spring;

//接口名必须以MBean结尾
public interface HelloMBean {
    public String getName();
    public void setName(String name);
    public void printHello();
}

对应的MBean接口实现类Hello:

package com.masi.jmx.spring;

//类名必须和接口MBean前的内容相同,即类名+MBean必须等于接口名
public class Hello implements HelloMBean {
    String name;
    @Override
    public void printHello() {
        System.out.println("你好,"+name);
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }
}

通过MBeanExporter自动扫描MBean

Spring上下文配置applicationContext-hello.xml如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="MBeanTestDomain:myobj=helloStandardMBean" class="com.masi.jmx.spring.Hello">
        <property name="name" value="Matt达蒙" />
    </bean>

    <bean id="mbServer_autodetect" class="org.springframework.jmx.export.MBeanExporter">
        <property name="autodetectModeName">
            <value>AUTODETECT_ALL</value>
        </property>
    </bean>

</beans>

注意:配置bean时,id必须是可创建ObjectName的domain: key1=value1, key2=value2[,...]格式,否则创建MBeanExporter bean时报错”Unable to register MBean…Key properties cannot be empty”

上面配置中,MBeanExporter会查找本地MBean Server,指定的探测模式autodetectModeName为AUTODETECT_ALL,这也是MBeanExporter的默认值(这个属性完全可以省略,不用配置),无需手动向MBean Server进行注册,便能管理配置的MBean对象“MBeanTestDomain:myobj=helloStandardMBean”。
对于探测模式autodetectModeName属性,Spring提供了4个取值:

  • AUTODETECT_NONE:不启用自动探测,需要手动向MBean Server进行注册,即通过MBeanExporter的beans属性进入注册;
  • AUTODETECT_MBEAN:在当前IOC容器中进行查找MBean组件;
  • AUTODETECT_ASSEMBLER:设置根据MBeanInfoAssembler的策略进行探测;
  • AUTODETECT_ALL:自动探测,是AUTODETECT_MBEAN和AUTODETECT_ASSEMBLER的并集。

另外,Spring的MBeanExporter也提供了autodetect属性,取值为true和false,指定对MBean组件的探测行为。


利用Spring将普通Bean注册为MBean

对于一个普通的Spring Bean,也可以作为MBean来进行管理,Spring可以很好地支持。

创建普通Java类

package com.masi.jmx.spring;

public class HelloNoMBean
{
    String name;
    public void printHello() {
        System.out.println("你好,"+name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

虽然HelloNoMBean类没有实现MBean管理接口,但可以通过spring提供的MBeanExporter类的beans属性直接注册为MBean。

通过MBeanExporter注册为MBean

Spring上下文配置applicationContext-hello.xml如下所示,MBeanExporter类的beans属性是个Map,key是MBean对象名称(即ObjectName)。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="helloNoMBean" class="com.masi.jmx.spring.HelloNoMBean">
        <property name="name" value="Matt马特" />
    </bean>

    <bean id="mbServer_beans" class="org.springframework.jmx.export.MBeanExporter">
        <property name="beans">
            <map>
                <entry key="MBeanTest:name=helloNoMBean" value-ref="helloNoMBean" />
            </map>
        </property>
    </bean>

</beans>

因为com.masi.jmx.spring.HelloNoMBean没有对应的MBean接口,所以默认情况下,该类中public的成员都会暴露出来,通过MBean Server可以管理。实际上,系统中MBean的某些属性或方法可能不需要暴露给外部进行管理,为了克服这种缺点,Spring提供了基于方法列表和接口定制的功能,可以将你所感兴趣的属性或方法暴露给外部管理。

加载Spring上下文测试

package com.masi.jmx.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloMain {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-*.xml");
        System.out.println("Spring context loaded!");
    }
}

Run As->Java Application 运行,通过JConsole或Java VisualVM连接本地JVM进行MBean操作。


参考


相关类和接口

ObjectName

javax.management.ObjectName
public class ObjectName extends Object implements Comparable<ObjectName>, QueryExp

表示 MBean 的对象名,或者能够与多个 MBean 名称相匹配的模式。
ObjectName由两部分组成,域:一个或多个键/值对,即 domain: key1=value1, key2=value2[,...],值可加引号也可不加引号
domian及属性(key或者value)都是支持正则的,比如:*表示匹配所有,?表示匹配一个字符。

构造方法

public ObjectName(String name)
根据给定的字符串构造一个对象名。

  • 参数:
    name - 对象名的字符串表示形式。
  • 抛出:
    • MalformedObjectNameException - 如果作为参数传递的字符串格式不正确。
    • NullPointerException - 如果 name 参数为 null。

MBeanServer

javax.management.MBeanServer
public interface MBeanServer extends MBeanServerConnection

在代理端进行 MBean 操作的接口。它包含创建、注册和删除 MBean 所需的方法,以及用于已注册 MBean 的存取方法。这是 JMX 基础设施的核心组件。
添加到 MBean 服务器中的所有 MBean 都会变成得可以管理:通过连接到该 MBeanServer 的连接器/适配器可以远程访问其属性和操作。Java 对象不能在 MBean 服务器中进行注册,除非它是兼容 JMX 的 MBean。
用户代码通常不实现此接口,应该使用 MBeanServerFactory 类中的某个方法获得实现此接口的对象

registerMBean()

ObjectInstance registerMBean(Object object, ObjectName name)
将某个预先存在的对象作为 MBean 注册到 MBean 服务器中。如果给定的对象名为 null,则该 MBean 必须提供自己的名称,方法是实现 MBeanRegistration 接口并从 preRegister 方法中返回名称。

  • 参数:
    • object - 要作为 MBean 注册的 MBean。
    • name - MBean 的对象名。可以为 null。
  • 返回:
    一个 ObjectInstance,它包含新注册的 MBean 的 ObjectName 和 Java 类名。如果包含的 ObjectName 是 n,则包含的 Java 类名是 getMBeanInfo(n).getClassName()。
  • 抛出:
    • InstanceAlreadyExistsException - 如果该 MBean 已经处于 MBean 服务器的控制之下。
    • MBeanRegistrationException - 如果 MBean 的 preRegister(MBeanRegistration 接口)方法已经抛出异常。不要注册该 MBean。
    • NotCompliantMBeanException - 如果此对象不是兼容 JMX 的 MBean
    • RuntimeOperationsException - 包装 java.lang.IllegalArgumentException:如果传入参数中的对象为 null 或者未指定对象名。

MBeanServerFactory

javax.management.MBeanServerFactory
public class MBeanServerFactory extends Object

提供 MBean 服务器引用,此类的所有方法都是static的,所以没有此类的实例。

findMBeanServer()

static ArrayList<MBeanServer> findMBeanServer(String agentId)
返回已注册 MBeanServer 对象的列表。已注册的 MBeanServer 对象是通过某个 createMBeanServer 方法创建并且随后未使用 releaseMBeanServer 释放的 MBeanServer。
参数:agentId,要检索的 MBeanServer 的代理标识符。如果此参数为 null,则返回此 JVM 中的所有已注册 MBeanServer。否则只返回其 id 等于 agentId 的 MBeanServer。MBeanServer 的 id 是其委托 MBean 的 MBeanServerId 属性。


ManagementFactory

java.lang.management.ManagementFactory
public class ManagementFactory extends Object

ManagementFactory 类是一种工厂类,用于获取Java平台的管理Bean。
此类由静态方法组成,每种静态方法都会返回一个或多个表示Java虚拟机组件的管理接口的平台MXBean。

getPlatformMBeanServer()

static MBeanServer getPlatformMBeanServer()
返回平台 MBeanServer。
第一次调用此方法时,将首先通过调用 MBeanServerFactory.createMBeanServer 方法创建平台 MBeanServer,然后通过使用类描述中定义的 MXBean 名称在此平台 MBeanServer 中注册平台 MXBean。在后续的调用中,此方法将直接返回最初创建的平台 MBeanServer。
动态创建和销毁的 MXBean(如内存池和管理器)将自动注册到平台 MBeanServer 和从中注销。
如果设置了系统属性 javax.management.builder.initial,将由指定的 MBeanServerBuilder 进行平台 MBeanServer 创建。
建议也将此平台用于注册平台 MXBean 之外的其他应用程序管理 Bean。这将允许所有 MBean 通过同一个 MBeanServer 发布,从而能够更方便地进行网络发布和发现。应该避免平台 MXBean 的名称冲突。

平台MXBean

平台MXBean是Java虚拟机中预定义的一种管理Bean,Java 虚拟机的每个平台 MXBean 都具有唯一的 ObjectName,以在平台 MBeanServer 中注册。

Java 虚拟机具有以下管理接口的单一实例:

管理接口 对象名称
ClassLoadingMXBean java.lang:type=ClassLoading
MemoryMXBean java.lang:type=Memory
ThreadMXBean java.lang:type=Threading
RuntimeMXBean java.lang:type=Runtime
OperatingSystemMXBean java.lang:type=OperatingSystem

Java 虚拟机具有以下管理接口的零个或一个实例:

管理接口 对象名称
CompilationMXBean java.lang:type=Compilation

Java 虚拟机可能具有以下管理接口的一个或多个实例:

管理接口 对象名称
GarbageCollectorMXBean java.lang:type=GarbageCollector,name=collector’s name
MemoryManagerMXBean java.lang:type=MemoryManager,name=manager’s name
MemoryPoolMXBean java.lang:type=MemoryPool,name=pool’s name

JMXConnectorServerFactory

javax.management.remote.JMXConnectorServerFactory
public class JMXConnectorServerFactory extends Object

用于创建 JMX API 连接器服务器的工厂。

newJMXConnectorServer()

static JMXConnectorServer newJMXConnectorServer(JMXServiceURL serviceURL, Map<String,?> environment, MBeanServer mbeanServer)throws IOException
创建位于给定地址的连接器服务器。结果服务器直到调用其 start 方法时才启动。

  • 参数:
    • serviceURL - 新的连接器服务器的地址。新的连接器服务器的 getAddress 方法返回的连接器服务器的实际地址不一定完全相同。例如,它可能包含一个端口号,而原始地址中并没有该端口号。
    • environment - 用于控制新连接器服务器的行为的一组属性。此参数可以为 null。此映射中关键字必须为字符串。每个关联值的适当类型取决于属性。此调用不改变 environment 的内容。
    • mbeanServer - 该连接器服务器连接到的 MBean 服务器。如果该连接器服务器将通过注册的方式连接到 MBean 服务器,则为 Null。
  • 返回:
    代表新的连接器服务器的 JMXConnectorServer。每次对此方法的成功调用都生成不同的对象。
  • 抛出:
    • NullPointerException - 如果 serviceURL 为 null。
    • IOException - 如果由于存在通信问题而导致无法建立连接器服务器。
    • MalformedURLException - 如果 serviceURL 中的协议无提供者。
    • JMXProviderException - 如果 serviceURL 中的协议有提供者,但提供者由于某种原因而无法使用。

JMXConnectorServer

javax.management.remote.JMXConnectorServer
public abstract class JMXConnectorServer extends NotificationBroadcasterSupport implements JMXConnectorServerMBean, MBeanRegistration, JMXAddressable

每个连接器服务器的超类。连接器服务器连接到 MBean 服务器。它侦听客户端连接请求并为每个请求创建连接。
连接器服务器或者通过在该 MBean 服务器上注册该连接器服务器,或者通过将 MBean 服务器传给其构造方法来与 MBean 服务器关联。
连接器服务器在创建时为非活动的。只有在调用了 start 方法后,它才开始侦听客户端连接。当调用了 stop 方法,或者将连接器服务器从其 MBean 服务器注销后,连接器服务器停止侦听客户端连接。

接口JMXConnectorServerMBean中的start()方法:激活连接器服务器,即开始侦听客户端连接。在连接器服务器已激活时,调用此方法没有任何作用。在连接器服务器已停止时,调用此方法将生成 IOException。


参考


工具

JConsole

JConsole是JDK自带的一个基于JMX的GUI工具,用于连接正在运行的JVM,不过此JVM需要使用可管理的模式启动。
启动Java\jdk1.8.0_111\bin中的JConsole,在本地进程中选择自己MBean进程,如图:

连接后切换到MBean标签页,MBean标签页展示了所有以一般形式注册到JVM上的MBeans,包括系统的MBean和自定义的MBean。
在左侧能看到创建ObjectName时自定义的domain名MBeanTest,以及MBean名StandardMBean,点开“属性”可输入属性值:

点开“操作”,点击按钮”printHello”可触发printHello()方法:

看Eclipse控制台,printHello()方法被调用。


Java VisualVM

JVM可视化监控工具,JDK中自带,在JDK安装目录的bin目录中。
官网:http://visualvm.java.net/

添加远程主机
应用程序->远程->右键”添加远程主机”->输入服务器ip->确定

添加JMX连接
在远程主机上右键->”添加JMX连接”->在”连接”中的ip后加上JMX远程端口,JMX远程端口一般为8888。

安装MBeans插件
插件中心 http://visualvm.java.net/pluginscenters.html
VisualVM中的在线插件搜索一直连接失败,选择手动下载插件安装。
从插件中心按照对应版本下载nbm格式插件,然后工具->插件->已下载->添加插件->打开下载好的nbm插件->按提示安装


上一篇 PostgreSQL-基础

下一篇 Apache-Camel

域名迁移公告
2017年12月20日起,本博客迁移到新域名madaimeng.com,旧域名masikkk.com不再更新内容,但将永久保持可访问!
阅读
4,408
阅读预计18分钟
创建日期 2016-12-19
修改日期 2017-07-20
类别
百度推荐