MBean与JMX

JMX是Java应用程序和网络管理的标准,用于监控系统状态和管理。MBeanServer是JMX的核心,作为管理对象的注册表。MBean是可管理资源的接口,标准MBean通过接口名称识别。JConsole工具可以用来监控MBean。源码分析涉及ManagementFactory.getPlatformMBeanServer()和MBeanServer.registerMBean()等关键方法。
摘要由CSDN通过智能技术生成


欢迎查看Eetal的第二十二篇博客–MBean与JMX

JMX

JMX(java Management Exetensions)在Java编程语言中定义了应用程序以及网络管理和监控的体系结构、设计模式、应用程序接口以及服务。
通常使用JMX来监控系统的运行状态或管理系统的某些方面,比如清空缓存、重新加载配置文件等
优点是可以非常容易的使应用程序被管理
伸缩性的架构使每个JMX Agent Service可以很容易的放入到Agent中,每个JMX的实现都提供几个核心的Agent Service,你也可以自己编写服务,服务可以很容易的部署,取消部署。
主要作用是提供接口,允许有不同的实现
简单来说,jmx是一个用来管理javaBean并可以进行监控的扩展规范,结合MBeanServer、rmi与http等可以作为一个服务监控和提供中心

MBeanServer

MBeanServer是JMX代理的核心组件。
它是在代理中向管理操作公开的对象的注册表。
向MBeanServer注册的任何对象都对管理应用程序可见。
MBeanServer仅公开MBean的管理接口,而不是它的直接对象引用。
您要从代理的Java VM外部管理的任何资源都必须在MBeanServer中注册为MBean。
MBeanServer还提供标准化接口,用于访问同一Java VM中的MBean,为本地对象提供操作可管理资源的所有好处。
需要注意的是,一般不使用MBeanServerFactory.createMBeanServer(),使用ManagementFactory.getPlatformMBeanServer()
后者在当前尚未在ManagementFactory中注册静态成员MBeanServer时,会先使用MBeanServerFactory.createMBeanServer()创建一个MBeanServer并将其注册到静态成员,后续每次调用会直接返回该成员实例
并且ManagementFactory.getPlatformMBeanServer()方法在第一次调用createMBeanServer()实例化MBeanServer以后,会读取PlatformComponent枚举的枚举值,将一些系统必要的MBean注册到MBeanServer
JConsole监控的MBeanServer就是在ManagementFactory中注册的静态成员MBeanServe
所以如果没有特殊配置的MBeanServer,jconsole是不会监控的

Agent

Java Management Extensions(JMX)Agent是一个在Java虚拟机(Java VM)中运行的管理实体.
充当MBean和管理应用程序(JConsole等)之间的联络人
Agent只是一个规范,一般会封装我们创建和启动MBeanServer以及注册MBean的过程在一个Agent行为里,方便启动

Agent Service

Agent Service是可以对MBeanServer中注册的MBean执行管理操作的对象。
通过将管理智能包含在代理中,JMX可帮助您构建更强大的管理解决方案。
Agent Service通常也是MBean,允许通过MBeanServer控制它们及其功能。
JMX规范定义了以下Agent Service:
通过管理applet(m-let)服务的动态类加载检索并实例化从网络动态下载的新类和本机库。
监视器观察MBean属性的数字或字符串值,并可以向其他对象通知几种类型的更改。
定时器提供调度机制,并且可以以预定间隔发送通知。
关系服务定义MBean之间的关联并维护关系的一致性。

Protocol Adaptors and Connectors

Protocol adaptors and connectors使代理可从远程(通过rmi或者http等协议)管理应用程序访问。
它们通过在MBean服务器中实例化和注册的MBean的特定协议提供视图。
它们使Java VM外部的管理应用程序能够:
获取或设置现有MBean的属性
对现有MBean执行操作
实例化并注册新的MBean
注册并接收MBean发出的通知
因此,要使JMX代理易于管理,它必须至少包含一个协议适配器或连接器。
Java SE平台包括标准RMI连接器。Agent可以包括任意数量的协议适配器和连接器,允许通过不同的协议同时远程管理和监视它

Protocol Adaptors

Protocol Adaptors通过给定协议提供JMX代理的管理视图。
它们将MBean和MBean服务器的操作调整为给定协议中的表示,
并可能调整为不同的信息模型,例如SNMP。Java SE平台不包括任何协议适配器作为标准。
连接到Protocol Adaptors的管理应用程序通常特定于给定的协议。
这通常是依赖于特定管理协议的传统管理解决方案的情况。
它们不是通过MBean服务器的远程表示来访问JMX代理,而是通过映射到MBeanServer的操作来访问JMX代理。

Connectors

Connectors用于将代理与为JMX技术启用的远程管理应用程序连接,即使用JMX规范的分布式服务开发的管理应用程序。
这种通信涉及Agent中的连接器服务器和管理器中的连接器客户端。
这些组件以特定协议的方式透明地传递管理操作。
JMX Remote API为MBeanServer提供远程接口,管理应用程序可以通过该接口执行操作。
Connectors特定于给定协议,但管理应用程序可以无差别地使用任何Connectors,因为它们具有相同的远程接口。

MBean

描述一个可管理的资源。是一个java对象,遵循以下一些规则:
1.必须是公用的,非抽象的类
2.必须有至少一个公用的构造器
3.必须实现它自己的相应的MBean接口或者实现javax.management.DynamicMBean接口
4.可选的,一个MBean可以实现javax.management.NotificationBroadcaster接口MBean的类型
MBean使用ObjectName以keyValue形式注册到MBeanServer上

Standard MBean

标准MBean,也是最简单的MBean,通过类实现的接口名称来识别MBean
接口名称以MBean结尾,实现类需要匹配接口名称的前半部分

public interface YytMBean{
   
	public void setName(String name);
	public String getName();
}
public class Yyt implements YytMBean{
   
	private String name;
	@Override
	public void setName(String name) {
   
		this.name = name;
	}
	@Override
	public String getName() {
   
		return name;
	}
}
public class YytAgent{
   
	private String domainName;
	private int rmiPort;
	public YytAgent(String domainName,int rmiPort) {
   
		this.domainName = domainName;
		this.rmiPort = rmiPort;
	}
	public void start() throws MalformedObjectNameException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException, IOException {
   
		//MBeanServerFactory.createMBeanServer();	//don't use this
		MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();	//use this instead
		
		YytMBean yytMBean = new Yyt();
		ObjectName objectName = new ObjectName(domainName+":name=Yyt");
		mBeanServer.registerMBean(yytMBean, objectName);
		
		LocateRegistry.createRegistry(rmiPort);//开启rmi端口监听,在jmxConnectorServer.start()时会根据serviceUrl建立一个rmiServer监听该rmi端口
		
		JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:"+rmiPort+"/"+domainName);
        JMXConnectorServer jmxConnectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mBeanServer);
        jmxConnectorServer.start();
        //开启jmx协议的监控服务器,因为java自带rmi的工具和依赖,可以直接开启,通过jconsole等支持jmx协议的客户端可以监控MBeanServer	
	}
}

使用JConsole工具监控

JConsole是java自带的监控程序,独立jre中没有,jdk下的jre具备

运行java应用时带上参数
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
关闭ssl和密码校验,开启远程监控端口8999,这时可以直接使用jconsole进行链接

或者在jdk\jre\lib\management目录下,复制一份jmxremote.password.template的文件,改名去掉.template后缀,并去掉文件末尾两行示例的用户名和密码注释,修改密码为自己想要的
运行加上参数
-Djava.rmi.server.hostname=应用所在服务器的ip或者域名
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=监控端口
-Dcom.sun.management.jmxremote.rmi.port=rmi监控端口(一般与监控端口保持一致)
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.ssl=false
这时使用JConsole链接会提示需要输入用户名和密码

在命令行输入jconsole运行jconsole程序
jconsole]
在jconsole的界面,因为是本地,直接选择本地进程,进入监控页面
点击导航栏的MBean即可看到我们注册的MBean在列表中
jconsole
还可以对Bean的属性值进行查看和设置
jconsole]

源码分析

ManagementFactory.getPlatformMBeanServer()

		SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
   
            Permission perm = new MBeanServerPermission("createMBeanServer");
            sm.checkPermission(perm);
        }

        if (platformMBeanServer == null) {
   
            platformMBeanServer = MBeanServerFactory.createMBeanServer();
            for (PlatformComponent pc : PlatformComponent.values()) {
   
                List<? extends PlatformManagedObject> list =
                    pc.getMXBeans(pc.getMXBeanInterface());
                for (PlatformManagedObject o : list) {
   
                    // Each PlatformComponent represents one management
                    // interface. Some MXBean may extend another one.
                    // The MXBean instances for one platform component
                    // (returned by pc.getMXBeans()) might be also
                    // the MXBean instances for another platform component.
                    // e.g. com.sun.management.GarbageCollectorMXBean
                    //
                    // So need to check if an MXBean instance is registered
                    // before registering into the platform MBeanServer
                    if (!platformMBeanServer.isRegistered(o.getObjectName())) {
   
                        addMXBean(platformMBeanServer, o);
                    }
                }
            }
            HashMap<ObjectName, DynamicMBean> dynmbeans =
                    ManagementFactoryHelper.getPlatformDynamicMBeans();
            for (Map.Entry<ObjectName, DynamicMBean> e : dynmbeans.entrySet()) {
   
                addDynamicMBean(platformMBeanServer, e.getValue(), e.getKey());
            }
            for (final PlatformManagedObject o :
                                       ExtendedPlatformComponent.getMXBeans()) {
   
                if (!platformMBeanServer.isRegistered(o.getObjectName())) {
   
                    addMXBean(platformMBeanServer, o);
                }
            }
        }
        return platformMBeanServer;

ManagementFactory中定义一个platformMBeanServer成员来装载创建好的MBeanServer
在执行该方法的第一步会先校验当前安全权限
在platformMBeanServer尚未绑定一个实例时,会先使用MBeanServerFactory.createMBeanServer()实例一个MBeanServer对象
接下来主要是读取PlatformComponent.values()以及别的枚举类和helper类的值和成员,将系统预设的MBean注册到MBeanServer

enum PlatformComponent {
   

    /**
     * Class loading system of the Java virtual machine.
     */
    CLASS_LOADING(
        "java.lang.management.ClassLoadingMXBean",
        "java.lang", "ClassLoading", defaultKeyProperties(),
        true, // singleton
        new MXBeanFetcher<ClassLoadingMXBean>() {
   
            public List<ClassLoadingMXBean> getMXBeans() {
   
                return Collections.singletonList(ManagementFactoryHelper.getClassLoadingMXBean());
            }
        }),

    /**
     * Compilation system of the Java virtual machine.
     */
    COMPILATION(
        "java.lang.management.CompilationMXBean",
        "java.lang", "Compilation", defaultKeyProperties(),
        true, // singleton
        new MXBeanFetcher<CompilationMXBean>() {
   
            public List<CompilationMXBean> getMXBeans() {
   
                CompilationMXBean m = ManagementFactoryHelper.getCompilationMXBean();
                if (m == null) {
   
                   return Collections.emptyList();
                } else {
   
                   return Collections.singletonList(m);
                }
            }
        }),
	.....
	}

MBeanServerFactory.createMBeanServer()

    public static MBeanServer createMBeanServer() {
   
        return createMBeanServer(null);
    }
	 public static MBeanServer createMBeanServer(String domain)  
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值