我的JMX心得 -- Server端

http://blog.csdn.net/derekjiang/article/details/4531952

最近在项目中用到了JMX,以前只是简略的知道JMX是干什么的,却没有深入了解过,当然也没有写过相关的代码,借着这个机会,正好学习一下。Google了n多大侠的相关帖子,对JMX有了一个初步的理解,这里总结出来,希望对大家有用。

 

关于什么是JMX,这里引用了网上找来的一个介绍:JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架。JMX是一套标准的代理和服务,实际上,用户可以在任何Java应用程序中使用这些代理和服务实现管理

 

老实说,看了这个介绍,我还是不太明白,用我们都能理解的大白话来说,JMX是一个框架,它提供了这样一种功能:通过使用JMX,我们可以实时查询应用程序中通过JMX向外公布的相应参数或者是其他应用数据,同时,我们也可以通过JMX来实时的调用应用程序使用JMX向外公布的接口,从而来实现一些操作。

 

准备工作


  JMX是一份规范,SUN依据这个规范在JDK(1.3、1.4、5.0)提供了JMX接口。而根据这个接口的实现则有很多种,比如Weblogic的JMX实现、MX4J、JBoss的JMX实现。在SUN自己也实现了一份,不过在JDK1.4之前,这件JMX实现(一些JAR包)是可选的,你得去它的网站上下载。JDK5.0则内嵌了进来,安装JDK5.0就可以开发基于JMX的代码了。

  但JDK5.0并非包含所有SUN的关于JMX的代码,有一些工具类是排除在JDK5.0之外的。下面根据所使用的JDK版本情况,谈一谈开发环境的准备。
1、JDK1.3、1.4
  去SUN网站下载SUN的JMX实现,共两个ZIP文件,下载网址: http://java.sun.com/products/JavaManagement/download.html
(1)jmx-1_2_1-ri.zip
   解压后的lib目录包含:jmxri.jar、jmxtools.jar
(2)jmx_remote-1_0_1_03-ri.zip
   解压后的lib目录包含:jmxremote.jar、jmxremote_optional.jar、rmissl.jar
  如果在DOS下用命令行开发,则把这五个JAR包加入到classpath系统变量中。如果你用Eclipse开发,则把JAR包加入到项目属性的Libratries(库)引用中。
2、JDK5.0以上
  JDK5.0的jre/lib/rt.jar已经包含了jmxri.jar、jmxremote.jar、rmissl.jar三个包的代码。如果你用到jmxtools.jar、jmxremote_optional.jar的类,则需要将这两个类加入到classpath或Eclipse的项目库引用中。
3、我使用的开发环境:JDK5.0 + Eclipse3.2。
  注:因为用到jmxtools.jar中的HtmlAdaptorServer类,所以将此包加入到项目库引用中。
Server端程序范例:
1. MBean接口
这是一个应用程序将要向外暴露的接口,在该接口中需要定义要公布的所有函数。
其中,如果存在一对对应的get方法和set方法,那么就默认有一个属性,且熟悉的名字就是get方法名字中get后面的部分。
包含在MBean中方法都将是可以被管理的。MBean起名是有规范的,就是原类名后加上MBean字样。
  1. package study.test.jmx;  
  2.   
  3. public interface HelloWorldMBean {  
  4.     public String getName();          
  5.     public void setName(String name);      
  6.     public void printHello();         
  7.     public void printHello(String whoName);    
  8. }  
2. 被管理的类
被管理的类需要实现相应的MBean接口,通过MBean接口中的方法来被管理。
  1. package study.test.jmx;  
  2.   
  3. public class HelloWorld implements HelloWorldMBean {  
  4.       
  5.     private String name;      
  6.       
  7.     public String getName() {      
  8.         return name;      
  9.     }      
  10.      
  11.     public void setName(String name) {      
  12.         this.name = name;      
  13.     }      
  14.      
  15.     public void printHello() {      
  16.         System.out.println("Hello World, " + name);      
  17.     }      
  18.      
  19.     public void printHello(String whoName) {      
  20.         System.out.println("Hello , " + whoName);      
  21.     }      
  22.   
  23. }  
3. 创建一个Agent类
Agent其实实现的是类似于Server的功能,他负责把JMX服务绑定到相应的URL,并将我们上面创建的被管理的类绑定到其中,使得外部可以访问。
  1. package study.test.jmx;  
  2.   
  3. import java.io.IOException;  
  4. import java.rmi.registry.LocateRegistry;  
  5. import java.rmi.registry.Registry;  
  6.   
  7. import javax.management.InstanceAlreadyExistsException;  
  8. import javax.management.MBeanRegistrationException;  
  9. import javax.management.MBeanServer;  
  10. import javax.management.MBeanServerFactory;  
  11. import javax.management.MalformedObjectNameException;  
  12. import javax.management.NotCompliantMBeanException;  
  13. import javax.management.ObjectName;  
  14. import javax.management.remote.JMXConnectorServer;  
  15. import javax.management.remote.JMXConnectorServerFactory;  
  16. import javax.management.remote.JMXServiceURL;  
  17.   
  18. import com.sun.jdmk.comm.HtmlAdaptorServer;  
  19.   
  20. public class HelloWorldAgent {  
  21.   
  22.     public static void main(String[] args) throws MalformedObjectNameException,  
  23.             NullPointerException, InstanceAlreadyExistsException,  
  24.             MBeanRegistrationException, NotCompliantMBeanException, IOException {  
  25.   
  26.         int rmiPort = 1099;  
  27.         String jmxServerName = "TestJMXServer";  
  28.           
  29.         // jdkfolder/bin/rmiregistry.exe 9999          
  30.         Registry registry = LocateRegistry.createRegistry(rmiPort);  
  31.   
  32.         MBeanServer mbs = MBeanServerFactory.createMBeanServer(jmxServerName);  
  33.         //MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();   
  34.       
  35.         HtmlAdaptorServer adapter = new HtmlAdaptorServer();  
  36.         ObjectName adapterName;  
  37.         adapterName = new ObjectName(jmxServerName + ":name=" + "htmladapter");  
  38.         adapter.setPort(8082);  
  39.         adapter.start();  
  40.         mbs.registerMBean(adapter, adapterName);  
  41.   
  42.         ObjectName objName = new ObjectName(jmxServerName + ":name=" + "HelloWorld");  
  43.         mbs.registerMBean(new HelloWorld(), objName);  
  44.           
  45.   
  46.         JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + rmiPort + "/" + jmxServerName);  
  47.         System.out.println("JMXServiceURL: " + url.toString());  
  48.         JMXConnectorServer jmxConnServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);  
  49.         jmxConnServer.start();  
  50.   
  51.     }  
  52. }  
说明:
1. Agent实现中的35行到40行为MBeanServer添加了一个 htmladapter,这样我们就可以通过网页的方式来进行管理。
 比如说上面我们实行的Agent,我们就可以通过http://localhost:8082来对程序进行管理。这里的8082就是htmladapter中设置的端口。
通过我们设定的MBean名字点击去,就可以进一步来管理我们的MBean

 从这张图我们可以看出,我们可以直接从网页上面来改动Name的值,并且也可以直接通过点击来调用相应的方法:printHello
 
 
 2. 如果大家在尝试写Agent程序时出现connection refused的异常的时候,不用怕,赶紧检查一下你的程序中是不是有这句话:
   Registry registry = LocateRegistry.createRegistry(rmiPort);
   LocateRegistry.createRegistry(int port)方法可以在某一特定端口创建名字服务,从而用户无需再手工启动rmiregistry
   或者,你也可以运行  jdkfolder/bin/rmiregistry.exe 9999
   其中jdkfolder是你的jdk的安装目录,9999是你要绑定的端口
   运行上面的命令和你在代码中添加上面那行code是一样的效果
   
 3. Agent的实现中的32行和33行是两种获取MBeanServer的方式。
    MBeanServer mbs = MBeanServerFactory.createMBeanServer(jmxServerName);
    这种方式主要用于JDK1.5以前
  MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
   这种方式是JDK1.5引入的。
   安全起见,当大家不能确定以后部署的机器上面安装的JDK是1.5以上的版本时,建议按照第一种方式。
  
 4. 绑定需要被管理的类
    ObjectName objName = new ObjectName(jmxServerName + ":name=" + "HelloWorld");
  mbs.registerMBean(new HelloWorld(), objName);
  这里我们可以看到,首先要给被绑定的类起一个名字,然后把这个名字和被管理的类一起注册到MBeanServer当中。
  
5. 将服务绑定到固定的URL上
  JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + rmiPort + "/" + jmxServerName);
  JMXConnectorServer jmxConnServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
  jmxConnServer.start();
  在start方法被调用后,服务就已经发布成功,我们就可以通过页面或者其他的方式来访问服务

 

 

===========

http://damies.iteye.com/blog/51804

前面所有看效果都是通过Html网页来看的。JDK5.0自带了一个jmx客户端,叫jconsole,位于c:\jdk\bin\jconsole.exe。我们来用用这个客户端来连接Mbean Server。
 
一、vm参数方式
 
1、还是用第一篇的那个HelloAgent,修改HelloAgent,将第一句:
MBeanServer server = MBeanServerFactory.createMBeanServer();
改为:MBeanServer server = ManagementFactory.getPlatformMBeanServer();
注:ManagementFactory的全路径为:java.lang.management.ManagementFactory
 
2、修改Eclipse的run选项,把“-Dcom.sun.management.jmxremote=HelloAgent”这一句加入到run选项中
 
3、运行HelloAgent,然后在Dos窗口输入“jconsole”来启到JConsole
4、单击“连接”
 
二、RMI方式
 
  还是用jconsole,但方式变了。这里不需要象上面那样修改Eclipse run的vm选项。
 
1、还是用第一篇的HelloAgent,加上一段代码,启动一个JMXConnectorServer服务

java 代码
  1. import javax.management.MBeanServer;   
  2. import javax.management.MBeanServerFactory;   
  3. import javax.management.ObjectName;   
  4. import javax.management.remote.JMXConnectorServer;   
  5. import javax.management.remote.JMXConnectorServerFactory;   
  6. import javax.management.remote.JMXServiceURL;   
  7.   
  8. import com.sun.jdmk.comm.HtmlAdaptorServer;   
  9.   
  10. public class HelloAgent {   
  11.     public static void main(String args[]) throws Exception {   
  12.         MBeanServer server = MBeanServerFactory.createMBeanServer();   
  13.         ObjectName helloName = new ObjectName("chengang:name=HelloWorld");   
  14.         Hello hello = new Hello();   
  15.         server.registerMBean(hello, helloName);   
  16.         ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082");   
  17.         HtmlAdaptorServer adapter = new HtmlAdaptorServer();   
  18.         server.registerMBean(adapter, adapterName);   
  19.         adapter.start();   
  20.         System.out.println("start.....");   
  21.   
  22.         // Create an RMI connector and start it   
  23.         JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/server");   
  24.         JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server);   
  25.         cs.start();   
  26.         System.out.println("rmi start.....");   
  27.     }   
  28. }   
2、在Dos运行一个命令:rmiregistry 9999
 
3、运行HelloAgent,然后再在dos下运行命令jconsole
输入service:jmx:rmi:///jndi/rmi://localhost:9999/server
 
三、总结
  连接MBeanServer的方式除了Html、JConsole,还有一些第三方的客户端,比较有名的是MC4j,通过这些客户端我们可以很容易去访问MBean。这也就是我们为什么要用JMX的其中一个原因:试想如果我自己搞一套标准,势必要自己开发一个客户端,那会是一个不小的工作量。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值