简介
JMX(Java Management Extensions) 是一个为应用程序植入管理功能的框架。
JMX 也是一套标准的代理和服务,实际上,用户可以在任何Java应用程序中使用这些代理和服务实现管理资源。
API
JMX 的API 主要在这两个地方:
- java.lang.management
- javax.management.*
资源
JMX 涉及到的是监控和管理,那么就会有涉及到管理资源。
我们要做的就是对资源进行监控和管理,监控是为了及时发现问题,以便能够及时提出正确的解决方案,避免损失。管理是为了预防问题的发生,同时也是为了使资源能够得到有效的利用,使利益最大化。
目前,JMX 可以实现的功能有:
- 监控硬件和平台的运行情况:包括服务器、操作系统等。
- 合理配置资源:比如内存的配置是否合理,CPU是否足够强大,硬盘容量是否足够。
- 收集应用运行的情况:比如说访问量多大,响应时间是否够快,哪个地区的访问人数最多。
- 在应用发生异常时能够及时定位问题所在:这是监控的核心之一。
术语
**管理资源(Manageable Source)**: 能够帮助系统或者你将要发生的活动正常运转的都是资源,这些只要能够被Java 类描述即可。
**管理组件(MBean, managed bean)**: 从资源角度来说,他是一个对抽象资源的一个描述。
由于管理组件是资源的抽象,所以管理应用也是直接面向MBean ,也就是MBean 会暴露给管理应用来操作和访问,通过MBean 中的方法和属性。
MBean 也有很多种类型,例如Standrad MBean、Dynamic MBean、Open MBean(目前还在改进中)、Model MBean。如无特殊说明,一般都是Standrad MBean。
**管理组件服务器(MBean Server)**: 简单来说就是一个容器,用来盛装和管理一组MBeans ,他是整个JMX 管理环境的核心。
由于其中有很多的MBean ,所以提供了一种注册机制来区分各个MBean ,每一个Mbean Server 的MBean 在注册的时候都要提供一个ObjectName 来区分彼此,MBean Server 通过这个ObjectName 来寻找每个MBean ,在JMX 中通过ObjectName 类来为每一个MBean 提供唯一标识,主要包含两部分:
- 域名: 这个域名就是要注册到MBean Server 中的名称标识相同,以便根据功能区分不同Mbean Server 中的MBean 。
- 键值对列表: 被用来唯一的标识MBean ,也提供了关于MBean 的相关信息。
当ObjectName 重复时,注册的时候就会抛出javax.management.InstanceAlreadyExistsException 异常。
JMX 代理(JMX Agent): 它提供一系列的服务来管理一系列的Mbeans ,他是MBean Server 的容器。
JMX 代理提供了一些服务,包括创建MBean 之间的关系、动态加载类、简单监视服务、计时器。
代理也可以有一系列的协议适配器(Protocol adapters) 和连接器(connectors) ,协议适配器和连接器也是Java 类,通常情况下也是MBeans ,这些适配器和连接器是提供转接功能而存在的,以便可以在远程使用不同的协议,通过客户端与这个代理连接(内部可以映射到一个外部的协议或者暴露代理给远程连接),这也就意味着JMX 代理可以被一系列的工具和管理协议使用,其本质就是一种插件式架构的体现,体现了可插拔的思想。
协议适配器和连接器(Protocol adapters and Connectors): 协议适配器和连接器都是JMX Agent 中的对象,将代理暴露给不同的管理应用和协议,就类似于不同的数据库驱动程序类似。一个JMX Agent 可以有很多个适配器和连接器,他们都是MBeans 。
通知(Notification): 通知是由MBeans 和MBean Server 提出的,其中封装了对应的具体事件和相应的数据。其他的Mbeans 或者Java 对象可以注册监听器来接收这些通知(观察者模式)。
JMX 架构图
由上图,JMX 的架构主要被分成三层:
- 基础层: 主要是Mbean ,被管理的资源。
- 适配层: MBean Server ,主要提供对资源的注册和管理。
- 接入层: 提供远程访问的入口。
简单示例
建立MBean 接口
1
2
3
4
5public interface HelloWorldMBean {
String getGreeting();
void setGreeting(String greeting);
void printGreeting();
}实现MBean 接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public 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);
}
}创建MBean Server 和JMX Agent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35public class HelloAgent implements NotificationListener {
private MBeanServer mbs;
public HelloAgent() {
this.mbs = MBeanServerFactory.createMBeanServer("HelloAgent"); // 创建MBean Server,并提供一个名称唯一标识Server
HelloWorld hw = new HelloWorld(); // 新建创建的MBean
ObjectName objName = null;
try{
objName = new ObjectName("HelloAgent:name=HelloWorld"); // 赋予一个名称唯一标识MBean,使用域名+属性列表来标识
mbs.registerMbean(hw, objName); // MBean Server 注册MBean
} catch(Exception e) {
e.printStackTrace();
}
startHtmlAdapterServer();
}
public void startHtmlAdapterServer() {
HtmlAdapterServer server = new HtmlAdapterServer(); // 创建一个Adapter ,便于测试
ObjectName adapterName = null;
try{
adapterName = new ObjectName("HelloAgent:name=adapter,port=9902"); // 赋予唯一标识的名称
server.setPort(9902); // Adapter 设置端口
mbs.registerMbean(server, adapterName); // MBean Server 注册Mbean
server.start(); // Adapter 启动
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println("HelloAgent is running!");
HelloAgent agent = new HelloAgent();
}
}需要引入jmxtools.jar 包到classpath中。
个人备注
此博客内容均为作者学习所做笔记,侵删!
若转作其他用途,请注明来源!