JMX简单入门
在一个系统中常常会有一些配置信息,比如服务的IP地址,端口号什么的,那么如何来来处理这些可配置项呢?
- 程序新手一般是写死在程序里,到要改变时就去改程序,然后再编译发布;
- 程序熟手则一般把这些信息写在一个配置文件里(JAVA一般都是*.properties文件),到要改变时只要改配置文件,但还是重新启动系统,以便读取配置文件里的新值;
- 程序好手则会写一个段代码,把配置值缓存起来,系统在读值的时候,先看看配置文件有没有更动,如有更改则重读一遍,否则从缓存里读取值;
- 程序高手则懂得取物为我所用,用JMX!把配置属性集中在一个类,然后写一个叫MBean的东东,再配置一下就轻松搞定了。而且JMX自动提供了一个WEB页面来给你来改变这些配置信息;
看到上面的处理方式,你是否对JMX有些心动呢?!
什么是JMX? JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架。JMX是一套标准的代理和服务,实际上,用户可以在任何Java应用程序中使用这些代理和服务实现管理,从而灵活的开发无缝集成的系统、网络和服务管理应用。
JMX架构
那么我们先来看看JMX的架构,如下图

JMX分为三层,分别负责处理不同的事务。它们分别是:
- Instrumentation 层Instrumentation层主要包括了一系列的接口定义和描述如何开发MBean的规范。通常JMX所管理的资源有一个或多个MBean组成,因此这个资源可以是任何由Java语言开发的组件,或是一个JavaWrapper包装的其他语言开发的资源。
- Agent 层Agent 用来管理相应的资源,并且为远端用户提供访问的接口。Agent层构建在Intrumentation层之上,并且使用并管理 Instrumentation层内部描述的组件。通常Agent由一个MBeanServer和多个系统服务组成。另外Agent还提供一个或多个 Adapter或Connector以供外界的访问。JMX Agent并不关心它所管理的资源是什么。
- Distributed 层Distributed层关心Agent如何被远端用户访问的细节。它定义了一系列用来访问Agent的接口和组件,包括Adapter和Connector的描述。
再来了解一下JMX中的术语:
- MBean:是Managed Bean的简称。在JMX中MBean代表一个被管理的资源实例,通过MBean中暴露的方法和属性,外界可以获取被管理的资源的状态和操纵MBean的行为。事实上,MBean就是一个Java Object,同JavaBean模型一样,外界使用自醒和反射来获取Object的值和调用Object的方法,只是MBean更为复杂和高级一些。
- MBeanServer:MBean生存在一个MBeanServer中。MBeanServer管理这些MBean,并且代理外界对它们的访问。并且MBeanServer提供了一种注册机制,是的外界可以通过名字来得到相应的MBean实例。
- JMX Agent:Agent只是一个Java进程,它包括这个MBeanServer和一系列附加的MbeanService。当然这些Service也是通过MBean的形式来发布。
- Protocol Adapters and ConnectorsJMX Agent通过各种各样的Adapter和Connector来与外界(JVM之外)进行通信。同样外界(JVM之外)也必须通过某个Adapter和Connector来向JMX Agent发送管理或控制请求。Adapter 和Connector的区别在于:Adapter是使用某种Internet协议来与JMX Agent获得联系,Agent端会有一个对象 (Adapter)来处理有关协议的细节。比如SNMP Adapter和HTTP Adapter。而Connector则是使用类似RPC的方式来访问Agent,在Agent端和客户端都必须有这样一个对象来处理相应的请求与应答。比如RMI Connector。JMX Agent可以带有任意多个Adapter,因此可以使用多种不同的方式访问Agent。
示例代码
在JMX的项目中我们一般都会涉及到上述三层,在Instrumentation层定义了一系列接口和规范,而JMX的MBean有静态的(Standard)MBean和动态的(Dynamic)MBean两类,但它们都必须实现Instrumentation的接口,Dynamic MBean需要继承一个DynamicMBean接口,开发较复杂,但是可以在运 行时动态修改因此灵活而功能强大。
作为入门级的JMX,我们在这里先实现一个StandardMBean,它必须遵循一套规范:必须为每一个MBean定义一个接口,而且这个接口的名字必须是其被管理的资源的对象类的名称后面加上"MBean"。例如:我们的对象 为 net.oseye.HelloJMX,为了构造一个StandardMBean,我们必须定义的接口的名称为 net.oseye.HelloJMXMBean。Agent依赖StandardMBean接口来访问被管理的资源,因此需要在 HelloJMXMBean中定义相应的方法。
我的项目结构如下图
MBean接口(HelloJMXMBean.java)
package net.oseye.demoJMX;
public interface HelloJMXMBean{
void sayHello();
void setUserName(String userName);
String getUserName();
String getNowTime();
}
MBean的实现(HelloJMX.java)
package net.oseye.demoJMX;
public class HelloJMX implements HelloJMXMBean {
private String userName;
public void sayHello() {
if (this.userName == null) {
System.out.println("Nobody!");
} else {
System.out.println("Hello, " + this.userName);
}
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserName() {
return userName;
}
public String getNowTime() {
return Long.toString(System.currentTimeMillis());
}
}
管理MBean和Distributed(App.java)
package net.oseye.demoJMX; import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName; import com.sun.jdmk.comm.HtmlAdaptorServer; public class App {
public static void main(String[] args) throws InterruptedException, MalformedObjectNameException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException{
//Agent
MBeanServer mServer=MBeanServerFactory.createMBeanServer("oseye");
HelloJMX helloJMX=new HelloJMX();
ObjectName helloON=new ObjectName("oseye:name=helloJMX");
mServer.registerMBean(helloJMX, helloON); //Distributed
HtmlAdaptorServer htmlAdaptor=new HtmlAdaptorServer();
ObjectName htmlAdaptorON=new ObjectName("oseye:name=htmlAdaptor");
mServer.registerMBean(htmlAdaptor, htmlAdaptorON);
htmlAdaptor.setPort(9955);
htmlAdaptor.start();
System.out.println("started");
}
}
Agent层
- 首先需要建立一个MBeanServer,MBeanServer用来管理我们的MBean。我们通常是通过MBeanServer来获取我们MBean的信息,间接的调用MBean的方法;
- 生成我们的资源的一个对象。JMX Agent管理的资源和普通的Java对象并没有区别,因此使用通常的建立对象的方式即可;
- 显示的将这个对象注册到MBeanServer中去。JMX 使用SNMP规范中的ObjectName作为标识和查找MBean的方式;
Distributed层
- 这里使用HtmlAdaptor,支持Http访问协议,并且有一个不错的Html界面,类Agent层那样注册;
- 显示的设置HtmlAdaptor的端口号,并调用它的start()方法,事实上HtmlAdaptor是一个简单的 HttpServer,它将Http请求转换为JMX Agent的请求。
JMX是一份规范,SUN依据这个规范在JDK(1.3、1.4、5.0)提供了JMX接口。而根据这个接口的实现则有很多种,比如Weblogic 的JMX实现、MX4J、JBoss的JMX实现。
在SUN自己也实现了一份,不过在JDK1.4之前,这件JMX实 现(一些JAR包)是可选的,你得去它的网站上下载。JDK5.0则内嵌了进来,安装JDK5.0就可以开发基于MX的代码了。
但JDK5.0并非包含所有SUN的关于JMX的代码,有一些工具类是排除在JDK5.0之外的。JDK5.0的jre\lib\rt.jar已经包含了jmxri.jar、 jmxremote.jar、rmissl.jar三个包的代码。
而这里用到了HtmlAdaptorServer类,它在jmxtools.jar中,需要到这里下载jmx-1_2_1-ri.zip:http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html,解压后的lib目录包含:jmxri.jar、jmxtools.jar。
示例效果
运行项目,可以通过浏览器查看地址:http://localhost:9955/,如下图:

打开连接“name=helloJMX”连接,可以看到

- NowTime被作为get属性;
- UserName作为get/set属性;
- 点击sayHello按钮,可以看到TempTest会打印“Nobody!”;
- 你可以尝试给UserName赋值,再点击sayHello按钮....
扩展...
JMX也提供了一种通知(Notification)机制。这种通知是由用户决定的,当应用出现某种状况时,可以利用通知来提醒管理人员,以及动态MBean使用请自行扩展练习!
JMX简单入门的更多相关文章
- 用IntelliJ IDEA创建Gradle项目简单入门
Gradle和Maven一样,是Java用得最多的构建工具之一,在Maven之前,解决jar包引用的问题真是令人抓狂,有了Maven后日子就好过起来了,而现在又有了Gradle,Maven有的功能它都 ...
- [原创]MYSQL的简单入门
MYSQL简单入门: 查询库名称:show databases; information_schema mysql test 2:创建库 create database 库名 DEFAULT CHAR ...
- Okio 1.9简单入门
Okio 1.9简单入门 Okio库是由square公司开发的,补充了java.io和java.nio的不足,更加方便,快速的访问.存储和处理你的数据.而OkHttp的底层也使用该库作为支持. 该库极 ...
- emacs最简单入门,只要10分钟
macs最简单入门,只要10分钟 windwiny @2013 无聊的时候又看到鼓吹emacs的文章,以前也有几次想尝试,结果都是玩不到10分钟就退出删除了. 这次硬着头皮,打开几篇文章都看完 ...
- 【java开发系列】—— spring简单入门示例
1 JDK安装 2 Struts2简单入门示例 前言 作为入门级的记录帖,没有过多的技术含量,简单的搭建配置框架而已.这次讲到spring,这个应该是SSH中的重量级框架,它主要包含两个内容:控制反转 ...
- Docker 简单入门
Docker 简单入门 http://blog.csdn.net/samxx8/article/details/38946737
- Springmvc整合tiles框架简单入门示例(maven)
Springmvc整合tiles框架简单入门示例(maven) 本教程基于Springmvc,spring mvc和maven怎么弄就不具体说了,这边就只简单说tiles框架的整合. 先贴上源码(免积 ...
- git简单入门
git简单入门 标签(空格分隔): git git是作为程序员必备的技能.在这里就不去介绍版本控制和git产生的历史了. 首先看看常用的git命令: git init git add git comm ...
- 程序员,一起玩转GitHub版本控制,超简单入门教程 干货2
本GitHub教程旨在能够帮助大家快速入门学习使用GitHub,进行版本控制.帮助大家摆脱命令行工具,简单快速的使用GitHub. 做全栈攻城狮-写代码也要读书,爱全栈,更爱生活. 更多原创教程请关注 ...
随机推荐
- HTML 相同name 传递一个数组
今天发现一个很厉害的东西 在input表单中,name名称可以是一个,后面[],里面跟名称,和数组一样,传递到PHP中也是一个数组 <html> <body> <form ...
- C++第五天学习
回顾: 1.友元 friend 2.运算符重载 类型 operator运算符(参数表) 抽象.封装 类是面向对象程序设计中最基本的概念 类的背后隐藏的思想是数据抽象和封装 是进行封装和数据隐藏的工具, ...
- Struts2文件的上传
一.单文件的上传 表单的enctype属性: application/x-www-form-urlencoded:默认的编码方式. multipart/form-data:会以二进制的方式处理表单数 ...
- 以脚本方式直接执行修改密码的passwd命令
以脚本方式直接执行修改密码的passwd命令: 参考: http://bbs.csdn.net/topics/390001865 http://bbs.chinaunix.net/thread-993 ...
- PHP生成短信验证码
简单版本 <?php function generate_code($length = 6) { $min = pow(10 , ($length - 1)); $max = pow(10, $ ...
- spring mvc handler的三种方式
springmvc.xml 三种方式不能针对一个controller同时使用 <?xml version="1.0" encoding="UTF-8"?& ...
- Flex性能调优相关的一些总结
1.Performace包含4点:(1)Latency反应时间(2)Scalability:可伸缩性(3)Reliablity:稳定性(4)Availability:可用性2.运行时生命周期:Flex ...
- Vue.js自定义指令的用法与实例
市面上大多数关于Vue.js自定义指令的文章都在讲语法,很少讲实际的应用场景和用例,以致于即便明白了怎么写,也不知道怎么用.本文不讲语法,就讲自定义指令的用法. 自定义指令是用来操作DOM的.尽管Vu ...
- MySQL 存储表情字符
摘要 在 MySQL 中直接存储表情的时候,会出现无法插入数据的错误. 这是由于一般情况下,MySQL 的字符集是 utf8,而对于 emoji 表情的 mysql 的 utf8 字符集是不支持,需要 ...
- C# 6 与 .NET Core 1.0 高级编程 - 37 章 ADO.NET
译文,个人原创,转载请注明出处,有不对的地方欢迎指出与交流. 英文原文:Professional C# 6 and .NET Core 1.0 - 37 ADO.NET --------------- ...