Java分布式应用学习笔记08JMX规范与常用的监控场景

来源:互联网 发布:球球代点刷棒棒源码 编辑:程序博客网 时间:2024/05/20 14:23

转自:Java分布式应用学习笔记08JMX规范与常用的监控场景

1.  JMX规范

JMX是“Java管理扩展的”的缩写,它和其他JavaEE类似也是曾经的Sun提出的一种规范(规约),从名字上可以看出主要是负责系统管理。是一个为系统加入或者说扩展成有管理功能的规约,只要按照这套规约行事,您的系统,某些某块就具备被其他工具(例如JConsole)管理的能力。换句话说就是可以用JMX来监控咱们的系统运行情况,还有可以在运行时环境像Web Service、RMI一样调用系统管理类的一些方法。实现此规范的框架也很多:Spring、Tomcat、JBoss容器……

2.  场景简述

咱们先假设一个情景,夫妻二人。男的因为工作需要要去外地出差,因公司规定,出差不能带家属,女方不能跟过去啊。所以女方给他们2个人一个手机——HTC吧。里面有个小程序,叫做JMXImpl4Android。等到男方出差在外地了,在外地出差的城市,一天晚上和同事散步,路上遇到个发廊(各位男性朋友明白的啊)。此时远在另一个城市的妻子的手机突然响了,手机GIS定位信息告知妻子:“您的丈夫在一个发廊门前徘徊,请注意”。妻子急了,立刻给丈夫打电话:“你干嘛呢?”。丈夫战战栗栗,汗出如浆,乖乖的回酒店玩DOTA了!

我们来用Java消息扩展的视角来看看这个场景,咱们伟大一些相当于那个妻子,那个丈夫就相当于咱们的系统,出差事件相当于咱们将系统部署到了真正的远程的运行环境,妻子曾HTC手机给丈夫您可以理解成把丈夫打造成具有JMX规范的系统,换句话说:此丈夫可监控。因为一个小小的GIS应用就能让妻子随时监控丈夫的状态——想邪恶一把,并且还可以根据系统的状态进行相应的措施——打电话告诉丫的别想出轨,虽然新的婚姻法下来了,但是房子是老娘买的,出轨?你试试!

看到这里,大家估计明白了JMX是什么东西,干什么用的了。但是估计大家有一个疑问,这个和Java分布式系统有什么关系啊?在分布式系统中有时候我们需要监控各个分机器的状态,比如想知道机器此时此刻的Tomcat的运行状况如何,还可以根据状况调用相关的操作,比如shutdown服务、去除已部署的web工程等等与服务有关的操作。或者对于调度这些节点机的主控机器也可以进行监控,在远程使用一个JConsole调用即可。Ok,说了这么多,我们看示例吧,最后再来用实例解释JMX的那些晦涩的理论概念。

3.  监控本机程序

这种场景在实际中不太常用,对于本机的程序来说,需要监控,按需调用被托管的类方法还真不多。

相当于丈夫就在你面前,他的一举一动都在你眼皮底下,你还需要一个Android小程序去监控他吗?笔者使用的是Spring3的实现。所以先将Spring的包下载下来,放到项目的classpath中。

咱们先写一个最普通的JavaBean

Java代码  收藏代码
  1. <span style="font-size: small;">package jmx;  
  2.   
  3. public class HusbandLocal {  
  4.   
  5.     // 属性  
  6.     private String name;  
  7.     private int age;  
  8.     private String message;  
  9.   
  10.     // set,get  
  11.     public String getName() {  
  12.         System.out.println("name:"+name);  
  13.         return name;  
  14.     }  
  15.   
  16.     public void setName(String name) {  
  17.         this.name = name;  
  18.     }  
  19.   
  20.     public int getAge() {  
  21.         System.out.println("age:"+age);  
  22.         return age;  
  23.     }  
  24.   
  25.     public void setAge(int age) {  
  26.         this.age = age;  
  27.     }  
  28.   
  29.     public String getMessage() {  
  30.         System.out.println("message:"+message);  
  31.         return message;  
  32.     }  
  33.   
  34.     public void setMessage(String message) {  
  35.         this.message = message;  
  36.     }  
  37.   
  38.     // 额外的操作,方法  
  39.     public void call(String message) {  
  40.         System.out.println("丈夫的call:" + message);  
  41.     }  
  42.       
  43.     public void look(){  
  44.         System.out.println("发现发廊");  
  45.     }  
  46.       
  47.     public void playDOTA(){  
  48.         System.out.println("这个不用解释了吧~DOTA");  
  49.     }  
  50.   
  51. }  
  52. </span>  

 以上Bean我们将它像Web Service一样(但是不是啊)暴露成JMX托管服务类。配置Spring文件内容如下

Java代码  收藏代码
  1. <span style="font-size: small;"><?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
  5.   
  6.     <!-- 暴露监控设备 -->  
  7.     <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"  
  8.         lazy-init="false">  
  9.         <property name="beans">  
  10.             <map>  
  11.                 <entry key="bean:name=HusbandLocal" value-ref="HusbandLocal" />  
  12.             </map>  
  13.         </property>  
  14.     </bean>  
  15.   
  16.     <!-- mbean -->  
  17.     <bean id="HusbandLocal" class="jmx.HusbandLocal" />  
  18. </beans>  
  19. </span>  

 org.springframework.jmx.export.MBeanExporter是Spring暴露管理Bean(MBean)的核心类之一。它使用一个Map类型的属性——beans记录要暴露MBean的类。将咱们刚刚写的HusbandLocal以属性注入的方式注入进去。之后写一个加载Spring文件的main实例,开启服务。

Java代码  收藏代码
  1. <span style="font-size: small;">        // 加载配置文件  
  2.         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(  
  3.                 "applicationContext.xml");  
  4.   
  5.         // 通过死循环保证主线程一直运行  
  6.         while (true) {  
  7.   
  8.         }  
  9. </span>  

 

 点击进去后可以查看咱们刚才暴露的MBean,如下



 我们可以点击MBean的操作,比如playDOTA(),后台就调用了该方法。在这个界面还可以看到MBean的属性值,你叫他们状态也行。

如此,我们完成了一个本地监控MBean对象的小功能。不过就像原来说的,这有个问题就是咱们之前说的,这种本地场景不多见,不常用。Ok,咱们看看要想远程监控需要做些什么事情。

4.  监控远程程序

下面我们尝试在远程监控咱们这个“丈夫”。

首先在Spring配置文件增加以下内容

Java代码  收藏代码
  1. <span style="font-size: small;">    <!-- 远程连接 RMI方式-->  
  2.     <!--  
  3.         地址输入  
  4.         service:jmx:rmi://localhost/jndi/rmi://192.168.1.100:8080/myconnector  
  5.     -->  
  6.     <bean class="org.springframework.jmx.support.ConnectorServerFactoryBean"  
  7.         depends-on="rmiRegistry">  
  8.         <property name="objectName" value="connector:name=rmi" />  
  9.           
  10.         <!-- 远程连接的地址 -->  
  11.         <property name="serviceUrl"  
  12.             value="service:jmx:rmi://localhost/jndi/rmi://localhost:8080/myconnector" />  
  13.     </bean>  
  14.       
  15.     <!-- 使用JNDI-RMI的方式进行远程连接通讯,并且配置占用端口号 -->  
  16.     <bean id="rmiRegistry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">  
  17.         <property name="port" value="8080" />  
  18.     </bean></span>  

 刚才我们将我们的MBean注册到一个基于RMI访问方式的连接服务上(ConnectorServerFactoryBean),占用的端口是8080。这时启用jconsole以远程方式连接,不用输入密码,如下图所示

 

之后和在本地操作一样,可以监控MBean的属性状态,也可以进行相应的操作。

5.  监控Web容器

如果我们要监控一下Web服务器,比如Tomcat服务器的JVM状态怎么办?这种场景非常的常见。其实配置也很简单。我们打开{Tomcat_HOME}/bin/catalina.bat,在linux下是{Tomcat_HOME}/bin/catalina.sh文件。将原有的脚本

Java代码  收藏代码
  1. <span style="font-size: small;">set LOGGING_MANAGER=-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager</span>  

 替换成为

Java代码  收藏代码
  1. <span style="font-size: small;">rem 配置JMX服务端口  
  2. set JAVA_OPTS=%JAVA_OPTS% -Dcom.sun.management.jmxremote.port=10090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file="%CATALINA_BASE%\conf\logging.properties"  
  3. </span>  

 

我们运行startup.bat文件,之后开启JConsole,远程登录tomcat

 
之后即可查看远程Tomcat资源

 

 

而Tomcat自身这个容易也有很多模块支持JMX规范,可以通过JConsole进行一些MBean的管理

 

6.  监控JavaEE容器

 

说完Tomcat这种Web容器,不得不说说JavaEE容器,就将开源的JBoss拉出来看看,其实JBoss自身因为是一个JavaEE容器,而JMX是属于JavaEE5范畴内的规范,所以JBoss自身就拥有很多JMX的特性,比如咱们动态添加一个DataSource资源时候,后台的JBoss控制台console的界面就会自动更新运行时的状态,数据源的连接状态也能一览无余的显示给后台使用者。这些实际上都是JMX的特性。只不过结合了Web页面的UI罢了。其实基于Web页面,大家就能看到JBoss自身的运行状况了

 如果需要JConsole连上远端的JBoss,和Tomcat一样,需改一下配置文件run.bat,linux
的就不赘述了,将以下代码段

Java代码  收藏代码
  1. <span style="font-size: small;">if "x%JAVA_OPTS%" == "x" (  
  2.   set "JAVA_OPTS=-Dprogram.name=%PROGNAME%"  
  3. else (  
  4.   set "JAVA_OPTS=-Dprogram.name=%PROGNAME% %JAVA_OPTS%"  
  5. )  
  6. </span>  

 

替换成

Java代码  收藏代码
  1. <span style="font-size: small;">if "x%JAVA_OPTS%" == "x" (  
  2.   
  3.   set "JAVA_OPTS=-Dprogram.name=%PROGNAME% -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"  
  4.   
  5. else (  
  6.   set "JAVA_OPTS=-Dprogram.name=%PROGNAME% -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false %JAVA_OPTS%"  
  7. )  
  8. </span>  

 

之后启动JConsole即可远程连接JBoss,地址:192.168.1.100:9999

 

可以看出Tomcat与JBoss的消耗资源真的不是一个数量级的。

7.  总结

这次是介绍了JMX的使用场景和一些分布式系统中常用的配置和监控情形,对于JMX规范本身,尤其是重要的MBean并没有做过多的介绍,其实MBean有很多种情况,这一篇文章并不能尽述。知道他是干什么,遇到那些晦涩难懂的理论就不再惧怕了,有时间打算下次再详细说说JMX MBean的各种使用情况。

  • 查看图片附件
0 0
原创粉丝点击