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. 做全栈攻城狮-写代码也要读书,爱全栈,更爱生活. 更多原创教程请关注 ...
随机推荐
- java_web学习(1)理解JavaBean
JavaBean简介 JavaBean是一种特殊的 Java 类,它遵从一定的设计模式,开发工具和其他组件可以根据这种模式来调用JavaBean. JavaBean可以设计得像Swing组 ...
- DELPHI判断是否64位操作系统
function IsWin64: Boolean;var Kernel32Handle: THandle; IsWow64Process: function(Handle: Windows.TH ...
- AJAX 跨域请求的解决办法:使用 JSONP获取JSON数据
由于受到浏览器的限制,ajax不允许跨域通信.如果尝试从不同的域请求数据,会出现安全错误.如果能控制数据驻留的远程服务器并且每个请求都前往同一域,就可以避免这些安全错误.但是,如果仅停留在自己的服务器 ...
- javascript的字符串操作
一,把字符串的首字母大写返回一个新的字符串 1.1简单写法,把一个单词的首字母大写 String.prototype.firstUpperCase = function(){ return this[ ...
- 响应的系统设置的事件——重写onConfigurationChanged响应系统设置更改
如果程序需要监听系统设置的更改,则可以考虑重写Activity的onConfigurationChanged(Configuration newConfig)方法,该方法是一个基于回调的事件处理方法: ...
- TCMalloc
一. 原理 tcmalloc就是一个内存分配器,管理堆内存,主要影响malloc和free,用于降低频繁分配.释放内存造成的性能损耗,并且有效地控制内存碎片.glibc中的内存分配器是ptmalloc ...
- BootstrapTable(附源码) Bootstrap结合BootstrapTable的使用,分为两种模试显示列表。
引用的css: <link href="@Url.Content("~/Css/bootstrap.min.css")" rel="styles ...
- DataTables学习:从最基本的入门静态页面,使用ajax调用Json本地数据源实现前端开发深入学习,根据后台数据接口替换掉本地的json本地数据,以及报错的处理地方,8个例子(显示行附加信息,回调使用api,动态显示和隐藏列...),详细教程
一.DataTables 个人觉得学习一门新的插件或者技术时候,官方文档是最根本的,入门最快的地方,但是有时候看完官方文档,一步步的动手写例子,总会出现各种莫名其妙的错误,需要我们很好的进行研究出错 ...
- python关于列表的操作
列表是Python中最基本的数据结构,列表是最常用的Python数据类型,列表的数据项不需要具有相同的类型.列表中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类 ...
- POJ1221(整数划分)
UNIMODAL PALINDROMIC DECOMPOSITIONS Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 543 ...