码迷,mamicode.com
首页 > 其他好文 > 详细

监控应用服务器使用JMX监控Tomcat (转收藏)

时间:2015-10-21 18:54:35      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:


前言:做了一个监控应用服务器的项目(支持Tocmat、WebSphere、WebLogic各版本), 过程也算是磕磕绊绊,由于网上缺少相关资料,或者深陷于知识的海洋难以寻觅到有效的资料,因而走过不少弯路,遇过不少困难。为了留下点印记,给后来人留下 点经验之谈,助之少走弯路,故将这些经验整理出来,与大家分享。水平有限,难免疏漏,还望指正。如有疑问,欢迎留言,或者加入Q群参与讨 论:35526521。

一、激活Tomcat的JMX远程配置

要通过JMX远程监控Tomcat,首先需要激活Tomcat的JMX远程配置。

① 先修改Tomcat的启动脚本,windows下为bin/catalina.bat(linux下为catalina.sh),添加以下内容,8999是jmxremote使用的端口号,第二个false表示不需要鉴权:
Xml代码 

set JMX_REMOTE_CONFIG=-Dcom.sun.management.jmxremote 
  -Dcom.sun.management.jmxremote.port=8999
  -Dcom.sun.management.jmxremote.ssl=false
  -Dcom.sun.management.jmxremote.authenticate=false set CATALINA_OPTS=%CATALINA_OPTS% %JMX_REMOTE_CONFIG%

要注意以上语句的位置不能太后面,可以加在【if "%OS%" == "Windows_NT" setlocal】一句后的大段的注释后面。

参考官方说明:
http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html#Enabling_JMX_Remote


② 上面的配置是不需要鉴权的,如果需要鉴权则添加的内容为:
Xml代码 

set JMX_REMOTE_CONFIG=-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=8999
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password
-Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access set CATALINA_OPTS=%CATALINA_OPTS% %JMX_REMOTE_CONFIG%


③ 然后复制并修改授权文件
$JAVA_HOME/jre/lib/management下有jmxremote.access和jmxremote.password的模板文件,将两个文件复制到$CATALINA_BASE/conf目录下
◆ 修改$CATALINA_BASE/conf/jmxremote.access 添加内容:

     monitorRole readonly
     controlRole readwrite 

 


◆ 修改$CATALINA_BASE/conf/jmxremote.password 添加内容:

     monitorRole tomcat
     controlRole tomcat


注意: 如果进行了以上步骤导致Tomcat启动不了,那么很可能是密码文件的权限问题

需要修改jmxremote.password文件的访问权限,只有运行Tomcat的用户才能拥有访问权限 :
      Windows的NTFS文件系统下,选中文件,点右键 -->“属性”-->“安全”--> 点“高级”--> 点“更改权限”--> 去掉“从父项继承....”--> 弹出窗口中选“删除”,这样就删除了所有访问权限。再选“添加”--> “高级”--> “立即查找”,选中你的用户(或用户组,如果选用户不行那就选用户组),例administrator,点“确定",“确定"。来到权限项目窗口,勾选 “完全控制”,点“确定”,OK了。

官方的提示:
      The password file should be read-only and only accessible by the operating system user Tomcat is running as.

④ 重新启动Tomcat,在Windows命令行输入“netstat -a”查看配置的端口号是否已打开,如果打开,说明上面的配置成功了。

⑤ 使用jconsole测试JMX。
运行$JAVA_HOME/bin目录下的jconsole.exe,打开J2SE监视和管理控制台,然后建立连接,如果是本地的Tomcat则 直接选择然后点击连接,如果是远程的,则进入远程选项卡,填写地址、端口号、用户名、口令即可连接。。Mbean属性页中给出了相应的数 据,Catalina中是tomcat的,java.lang是jvm的。对于加粗的黑体属性值,需双击一下才可看内容。


二、使用JMX监控Tomcat示例代码
Java代码 

 1 String jmxURL = "service:jmx:rmi:///jndi/rmi://192.168.10.93:8999/jmxrmi"; 
 2 JMXServiceURL serviceURL = new JMXServiceURL(jmxURL); 
 3  
 4 Map map = new HashMap(); 
 5 // 用户名密码,在jmxremote.password文件中查看 
 6 String[] credentials = new String[] { "monitorRole", "tomcat" }; 
 7 map.put("jmx.remote.credentials", credentials); 
 8 JMXConnector connector = JMXConnectorFactory.connect(serviceURL, map); 
 9 MBeanServerConnection mbsc = connector.getMBeanServerConnection(); 
10  
11 // 端口最好是动态取得 
12 ObjectName threadObjName = new ObjectName("Catalina:type=ThreadPool,name=http-8080"); 
13 MBeanInfo mbInfo = mbsc.getMBeanInfo(threadObjName); 
14  
15 // tomcat的线程数对应的属性值 
16 String attrName = "currentThreadCount"; 
17 MBeanAttributeInfo[] mbAttributes = mbInfo.getAttributes(); 
18 System.out.println("currentThreadCount:" + mbsc.getAttribute(threadObjName, attrName)); 


三、完整的示例代码文件
Java代码 

  1 import java.lang.management.MemoryUsage; 
  2 import java.text.SimpleDateFormat; 
  3 import java.util.Date; 
  4 import java.util.Formatter; 
  5 import java.util.HashMap; 
  6 import java.util.Iterator; 
  7 import java.util.Map; 
  8 import java.util.Set; 
  9  
 10 import javax.management.MBeanAttributeInfo; 
 11 import javax.management.MBeanInfo; 
 12 import javax.management.MBeanServerConnection; 
 13 import javax.management.ObjectInstance; 
 14 import javax.management.ObjectName; 
 15 import javax.management.openmbean.CompositeDataSupport; 
 16 import javax.management.remote.JMXConnector; 
 17 import javax.management.remote.JMXConnectorFactory; 
 18 import javax.management.remote.JMXServiceURL; 
 19  
 20 public class JMXTest { 
 21  
 22     /**
 23      * @param args
 24      */ 
 25     public static void main(String[] args) { 
 26         try { 
 27  
 28             String jmxURL = "service:jmx:rmi:///jndi/rmi://127.0.0.1:8999/jmxrmi"; 
 29  
 30             JMXServiceURL serviceURL = new JMXServiceURL(jmxURL); 
 31  
 32             Map map = new HashMap(); 
 33             String[] credentials = new String[] { "monitorRole", "tomcat" }; 
 34             map.put("jmx.remote.credentials", credentials); 
 35             JMXConnector connector = JMXConnectorFactory.connect(serviceURL, 
 36                     map); 
 37             MBeanServerConnection mbsc = connector.getMBeanServerConnection(); 
 38  
 39             // 端口最好是动态取得 
 40             ObjectName threadObjName = new ObjectName( 
 41                     "Catalina:type=ThreadPool,name=http-8080"); 
 42             MBeanInfo mbInfo = mbsc.getMBeanInfo(threadObjName); 
 43  
 44             String attrName = "currentThreadCount";// tomcat的线程数对应的属性值 
 45             MBeanAttributeInfo[] mbAttributes = mbInfo.getAttributes(); 
 46             System.out.println("currentThreadCount:" 
 47                     + mbsc.getAttribute(threadObjName, attrName)); 
 48  
 49             // heap 
 50             for (int j = 0; j < mbsc.getDomains().length; j++) { 
 51                 System.out.println("###########" + mbsc.getDomains()[j]); 
 52             } 
 53             Set MBeanset = mbsc.queryMBeans(null, null); 
 54             System.out.println("MBeanset.size() : " + MBeanset.size()); 
 55             Iterator MBeansetIterator = MBeanset.iterator(); 
 56             while (MBeansetIterator.hasNext()) { 
 57                 ObjectInstance objectInstance = (ObjectInstance) MBeansetIterator 
 58                         .next(); 
 59                 ObjectName objectName = objectInstance.getObjectName(); 
 60                 String canonicalName = objectName.getCanonicalName(); 
 61                 System.out.println("canonicalName : " + canonicalName); 
 62                 if (canonicalName 
 63                         .equals("Catalina:host=localhost,type=Cluster")) { 
 64                     // Get details of cluster MBeans 
 65                     System.out.println("Cluster MBeans Details:"); 
 66                     System.out 
 67                             .println("========================================="); 
 68                     // getMBeansDetails(canonicalName); 
 69                     String canonicalKeyPropList = objectName 
 70                             .getCanonicalKeyPropertyListString(); 
 71                 } 
 72             } 
 73             // ------------------------- system ---------------------- 
 74             ObjectName runtimeObjName = new ObjectName("java.lang:type=Runtime"); 
 75             System.out.println("厂商:" 
 76                     + (String) mbsc.getAttribute(runtimeObjName, "VmVendor")); 
 77             System.out.println("程序:" 
 78                     + (String) mbsc.getAttribute(runtimeObjName, "VmName")); 
 79             System.out.println("版本:" 
 80                     + (String) mbsc.getAttribute(runtimeObjName, "VmVersion")); 
 81             Date starttime = new Date((Long) mbsc.getAttribute(runtimeObjName, 
 82                     "StartTime")); 
 83             SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
 84             System.out.println("启动时间:" + df.format(starttime)); 
 85  
 86             Long timespan = (Long) mbsc.getAttribute(runtimeObjName, "Uptime"); 
 87             System.out.println("连续工作时间:" + JMXTest.formatTimeSpan(timespan)); 
 88             // ------------------------ JVM ------------------------- 
 89             // 堆使用率 
 90             ObjectName heapObjName = new ObjectName("java.lang:type=Memory"); 
 91             MemoryUsage heapMemoryUsage = MemoryUsage 
 92                     .from((CompositeDataSupport) mbsc.getAttribute(heapObjName, 
 93                             "HeapMemoryUsage")); 
 94             long maxMemory = heapMemoryUsage.getMax();// 堆最大 
 95             long commitMemory = heapMemoryUsage.getCommitted();// 堆当前分配 
 96             long usedMemory = heapMemoryUsage.getUsed(); 
 97             System.out.println("heap:" + (double) usedMemory * 100 
 98                     / commitMemory + "%");// 堆使用率 
 99  
100             MemoryUsage nonheapMemoryUsage = MemoryUsage 
101                     .from((CompositeDataSupport) mbsc.getAttribute(heapObjName, 
102                             "NonHeapMemoryUsage")); 
103             long noncommitMemory = nonheapMemoryUsage.getCommitted(); 
104             long nonusedMemory = heapMemoryUsage.getUsed(); 
105             System.out.println("nonheap:" + (double) nonusedMemory * 100 
106                     / noncommitMemory + "%"); 
107  
108             ObjectName permObjName = new ObjectName( 
109                     "java.lang:type=MemoryPool,name=Perm Gen"); 
110             MemoryUsage permGenUsage = MemoryUsage 
111                     .from((CompositeDataSupport) mbsc.getAttribute(permObjName, 
112                             "Usage")); 
113             long committed = permGenUsage.getCommitted();// 持久堆大小 
114             long used = heapMemoryUsage.getUsed();// 
115             System.out.println("perm gen:" + (double) used * 100 / committed 
116                     + "%");// 持久堆使用率 
117  
118             // -------------------- Session --------------- 
119             ObjectName managerObjName = new ObjectName( 
120                     "Catalina:type=Manager,*"); 
121             Set<ObjectName> s = mbsc.queryNames(managerObjName, null); 
122             for (ObjectName obj : s) { 
123                 System.out.println("应用名:" + obj.getKeyProperty("path")); 
124                 ObjectName objname = new ObjectName(obj.getCanonicalName()); 
125                 System.out.println("最大会话数:" 
126                         + mbsc.getAttribute(objname, "maxActiveSessions")); 
127                 System.out.println("会话数:" 
128                         + mbsc.getAttribute(objname, "activeSessions")); 
129                 System.out.println("活动会话数:" 
130                         + mbsc.getAttribute(objname, "sessionCounter")); 
131             } 
132  
133             // ----------------- Thread Pool ---------------- 
134             ObjectName threadpoolObjName = new ObjectName( 
135                     "Catalina:type=ThreadPool,*"); 
136             Set<ObjectName> s2 = mbsc.queryNames(threadpoolObjName, null); 
137             for (ObjectName obj : s2) { 
138                 System.out.println("端口名:" + obj.getKeyProperty("name")); 
139                 ObjectName objname = new ObjectName(obj.getCanonicalName()); 
140                 System.out.println("最大线程数:" 
141                         + mbsc.getAttribute(objname, "maxThreads")); 
142                 System.out.println("当前线程数:" 
143                         + mbsc.getAttribute(objname, "currentThreadCount")); 
144                 System.out.println("繁忙线程数:" 
145                         + mbsc.getAttribute(objname, "currentThreadsBusy")); 
146             } 
147  
148         } catch (Exception e) { 
149             e.printStackTrace(); 
150         } 
151     } 
152  
153     public static String formatTimeSpan(long span) { 
154         long minseconds = span % 1000; 
155  
156         span = span / 1000; 
157         long seconds = span % 60; 
158  
159         span = span / 60; 
160         long mins = span % 60; 
161  
162         span = span / 60; 
163         long hours = span % 24; 
164  
165         span = span / 24; 
166         long days = span; 
167         return (new Formatter()).format("%1$d天 %2$02d:%3$02d:%4$02d.%5$03d", 
168                 days, hours, mins, seconds, minseconds).toString(); 
169     } 
170 } 

 



监控应用服务器使用JMX监控Tomcat (转收藏)

标签:

原文地址:http://www.cnblogs.com/zhengah/p/4898444.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!