jmx初步 控制台检监控技术探索

jmx资源:

ibm J2EE专题:
http://www.ibm.com/developerworks/cn/java/j-jee/j2ee-services.html#J2EEZ296
中的jmx部分
其中
http://www.ibm.com/developerworks/cn/java/j-lo-jse63/
这篇比较重要

Oracle的教程与example源代码
http://download.oracle.com/javase/1.5.0/docs/guide/jmx/tutorial/tutorialTOC.html
http://download.oracle.com/javase/1.5.0/docs/guide/jmx/examples.html
http://download.oracle.com/javase/1.5.0/docs/guide/management/agent.html

在其例子Basic中有个问题,rmiServer不好绑定,其原因是缺少LocateRegistry.createRegistry(connectorPort);这一句
具体见 http://www.iteye.com/topic/358379

基本概念:
MBean 规定了标准 MBean 也要实现一个接口,所有向外界公开的方法都要在这个接口中声明。否则,管理系统就不能从中获得相应的信息。此外,该接口的名字也有一定的规范:即在标准 MBean 类名之后加上“MBean”后缀。若 MBean 的类名叫做 MBeansName 的话,对应的接口就要叫做 MBeansNameMBean。

动态MBean要实现DynamicMBean接口。

MXBean(注意多个X)是OpenBean(1.6以后才有官方文档介绍) 
Open MBean 与其它动态 MBean 的唯一区别在于,前者对其公开接口的参数和返回值有所限制 —— 只能是基本类型或者 javax.management.openmbean包内的 ArrayType、CompositeType、TarbularType 等类型。这主要是考虑到管理系统的分布,很可能远端管理系统甚至 MBServer 层都不具有 MBean 接口中特殊的类。

还有个区别,标准mbean要求接口和实现类在同一个包中,而open bean则没有这个要求。[http://blogs.oracle.com/jmxetc/entry/javax_management_standardmbean_when_and] 

Model Bean
具有持久化,日志等功能,但要看具体容器的支持。


jmx客户端和jmx服务端:
客户端通过RMI连接服务端获取信息。
服务端一般是某个容器或服务器的附加功能,它们依据jmx规范写出容器的管理Mbean。tomcat,mule都实现了。

getPlatformMBeanServer是获得已存在的server,一般是本地虚拟机上的

如果注册在 getPlatformMBeanServer上,则可通过增加JVM参数来增加jmx控制,参见http://kazge.com/archives/516.html

这种方式与创建专门的MBeanServer所不同的是自动会包含Platform MBeans(java.lang/com.sun.management)Logging Management(java.util.logging)这些个MBean,参见

http://download.oracle.com/javase/1.5.0/docs/guide/management/overview.html

访问远程jvm的技术jstad:
http://download.oracle.com/javase/6/docs/technotes/tools/share/jstatd.html
注意里面的申明:可能在以后不支持。
NOTE: This utility is unsupported and may or may not be available in future versions of the JDK. It is not currently available on the Windows 98 and Windows ME platforms.
只能监控,不能操作。
需要制定policy -J-Djava.security.policy 和hostname(nat环境下)-Djava.rmi.server.hostname=
否则会有问题
参见
http://hi.baidu.com/passedbylove/blog/item/b600b2a8b6ebc2bacb130cc5.html
http://hi.baidu.com/luohuazju/blog/item/36ddd6103a51b2f6c3ce79c0.html

visualvm用于监测远程机器:
http://java.net/projects/visualvm/content/jmx_connections.html
但是如果远程jvm没有开放监测端口,可使用设置com.sun.management.jmxremote.*参数的办法,让每个你想检测的程序都开放一个检测端口(这个就不太好了,如果一个平台里面有许多应用,那么开那么多的端口本身就很耗资源。)



服务端注册/创建:

         MBeanServer mbs = MBeanServerFactory.createMBeanServer(); 
         String domain = mbs.getDefaultDomain(); 
         
         MemoryMXBean obean = ManagementFactory.getMemoryMXBean(); 
         ObjectName on = new ObjectName(domain+":type=abc"); //名字只是个key,只要客户端与之对应就找得到 
         mbs.registerMBean(obean, on); 

客户端查找:

MemoryMXBean proxy = JMX.newMXBeanProxy(mbsc, stdMBeanName, MemoryMXBean.class); 
//注意上面多了个X,因为是查找Open MBean,其他类型应该使用newMBeanProxy 

监听服务断开事件

JMXConnector jmxc =...;
jmxc.addConnectionNotificationListener(new NotificationListener(){

				public void handleNotification(Notification notification, Object handback)
				{			
					//jmx.remote.connection.closed---Client has been closed
					log(notification.getType() + "---" + notification.getMessage());					
				}}, null, null);

一旦出发close事件,则JMXConnector就不可用了,需要重新连接!


对于每个jmx连接,都可以从其java.lang域中找到如CPU,内存之类的信息。


查找功能:

http://weblogs.java.net/blog/2008/04/25/query-language-jmx-api

但是这里面有些是JDK7才支持。

各中间件
TOMCAT:

http://tomcat.apache.org/tomcat-5.5-doc/monitoring.html

MBean操作见http://kazge.com/archives/515.html

这上面只是说了ant来操作.

我的考虑是每机器建立一个总体服务集成所有本地的jmx服务,这种情况下只需要Tomcat提供本地可访问即可,也不必配置权限密码等。

很简单,只要在tomcat启动脚本里设置JVM参数-Dcom.sun.management.jmxremote即可。这样就可在jconsole 里面看得到了。[这是错误的,我使用myeclipse启动所以看得见,而与加没加-Dcom.sun.management.jmxremote没关系,任何本地运行的java程序都应该在jconsole里面看得到,但是使用tomcat脚本启动tomcat5.5却看不到!myeclips为什么看得到,因为它是直接调用bootstrap.jar这个包启动的,至于这和脚本启动有什么区别,我还没搞清楚,因此,还是为Tomcat直接配置个jmx端口吧!!]

Tomcat的jmx配置其文档上有,只是说加参数没有说清楚加在哪里,应该加在catalina.sh/bat中。

还没有发布app的mbean,只有通过web方式:

Tomcat5.5 http://tomcat.apache.org/tomcat-5.5-doc/manager-howto.html

Tomcat6 http://tomcat.apache.org/tomcat-6.0-doc/manager-howto.html


jconsole源码:

http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules-sun/tools/sun.tools.jconsole.htm

LocalVirtualMachine里面:查找可attach的vm

下面两个方法从其源码里面整理出来

//这个方法是sun私有的,没有公开 
public static void showMonitoredVMs() 
{ 
     MonitoredHost host; 
     Set vms; 
     try 
     { 
         host = MonitoredHost.getMonitoredHost(new HostIdentifier((String) null)); 
         vms = host.activeVms(); 
     } 
     catch (java.net.URISyntaxException sx) 
     { 
         throw new InternalError(sx.getMessage()); 
     } 
     catch (MonitorException mx) 
     { 
         throw new InternalError(mx.getMessage()); 
     } 
     for (Object vmid : vms) 
     { 
         if (vmid instanceof Integer) 
         { 
             int pid = ((Integer) vmid).intValue(); 
             String name = vmid.toString(); // default to pid if name not available 
             boolean attachable = false; 
             String address = null; 
             try 
             { 
                 MonitoredVm mvm = host.getMonitoredVm(new VmIdentifier(name)); 
                 // use the command line as the display name 
                 name = MonitoredVmUtil.commandLine(mvm); 
                 attachable = MonitoredVmUtil.isAttachable(mvm); 
                 address = ConnectorAddressLink.importFrom(pid); 
                 mvm.detach(); 
                 log("----------------name[%s] attachable[%s] address[%s]----------", name, attachable, address); 
                 showConnectionMbeans(address); 
             } 
             catch (Exception x) 
             { 
                 // ignore 
             } 
         } 
     } 
} 

//这个方法sun定义了规范 
public static void showAttachableVMs() 
{ 
     List<VirtualMachineDescriptor> vms = VirtualMachine.list(); 
     for (VirtualMachineDescriptor vmd : vms) 
     { 
         try 
         { 
             Integer vmid = Integer.valueOf(vmd.id()); 
             
                 boolean attachable = false; 
                 String address = null; 
                 try 
                 { 
                     VirtualMachine vm = VirtualMachine.attach(vmd); 
                     attachable = true; 
                     Properties agentProps = vm.getAgentProperties(); 
                     address = (String) agentProps.get("com.sun.management.jmxremote.localConnectorAddress"); 
                     vm.detach(); 
                     log("name[%s] attachable[%s] address[%s]", vmd.displayName(), attachable, address); 
                 } 
                 catch (AttachNotSupportedException x) 
                 { 
                     // not attachable 
                 } 
                 catch (IOException x) 
                 { 
                     // ignore 
                 } 
             
         } 
         catch (NumberFormatException e) 
         { 
             // do not support vmid different than pid 
         } 
     } 
} 

MULE:

这个花了我一些功夫,我想按照加JVM参数的方式来本地访问mule的Mbean,结果总是看不到任何mbean,最后发现mule加虚拟机参数是

http://www.mulesoft.org/documentation/display/MULE3INSTALL/Passing+Additional+Arguments+to+the+JVM+to+Control+Mule

mule -config xxx.config -M-Dcom.sun.management.jmxremote

它要多加个-M,即使你改launcher.bat里面的脚本加参数也要这样

另外要配置jmx自带的mbean<management:jmx-server ></management:jmx-server>(参见手册,注意要加好对应的xml shcema,如果没加,mule报错说配置文件找不到,让你无法定位。)

连通后发现MBean domain很古怪,要想指定dmian需要加参数

-M-Dmule.serverId=YOUR_MULE_SERVER_ID

这里比较纠结,所以,还是建议直接使用默认的配置<management:jmx-default-config port="99999" registerMx4jAdapter="true">(registerMx4jAdapter是对mx4j的端口,默认9999,可以设置为false),然后启动mule,你可以看到mule启动日志里面写出了最终的暴露出来的jmx和rmi端口。但是这样就暴露了两个重复的端口,一个是你在启动脚本里指定的jmx端口,另外一个就是jmx-default-config配置的端口。

只有配置了上面jmx自带的agent,才能看到较多的jmx信息。

OPENFIRE:

添加jvm参数见文档install-guide.html中Custom Parameers 部分,各平台不一样。但是jmx连通后没有openfire的mbean。所以还得自己写插件。

windows上 JVM参数可加在openfired.vmoptions (这个是install4j的配置) 中,linux上就不能,按照文档来,少走弯路。

数据库:

hibernate+JMX 主要是jbbc可进行的操作(性能状态,怎删改查),要想用它启动数据库是不行的也是没必要的。hibernate自带的主要是

HibernateServiceMBean可用性不大,主要为hibernate配置
StatisticsServiceMBean监控

 

环境系统:

java.lang.management包中提供的信息只是硬件静态信息,对于CPU时间只是本虚拟机的CPU时间,

其文档

因此要获得整体机器的动态信心,还得另想办法:

使用sigar http://sourceforge.net/projects/sigar/

jdmk http://java.sun.com/products/jdmk/ 这个似乎不好用

这个是较早的探索,如今sigar应该足够了!

 http://www.ibm.com/developerworks/cn/java/j-rtm3/index.html


Total views.

© 2013 - 2018. All rights reserved.

Powered by Hydejack v6.6.1