前言:做了一个监控应用服务器的项目(支持Tocmat、WebSphere、WebLogic各版本), 过程也算是磕磕绊绊,由于网上缺少相关资料,或者深陷于知识的海洋难以寻觅到有效的资料,因而走过不少弯路,遇过不少困难。为了留下点印记,给后来人留下 点经验之谈,助之少走弯路,故将这些经验整理出来,与大家分享。水平有限,难免疏漏,还望指正。如有疑问,欢迎留言,或者加入Q群参与讨 论:35526521。
监控Tomcat的常见方案有两种,比较如下:
方案一、使用Tomcat提供的manager应用进行数据采集
◆ 可以使用现有的成熟代码,减少工作量
◆ 支持各不同版本时无差别
◆ 可能存在特殊需求而manager不能满足的情况
◆ 最重要的一个优点是,配置比较简单
方案二、使用JMX接口开发监控程序
◆ 全部代码需要从零开始,代码量较大
◆ 支持各不同版本比较麻烦,每个版本可能有差异
◆ 可支配性强
◆ 最重要的一个缺点是,配置比较麻烦
方案一、使用 Tomcat提供的manager应用进行数据采集
Applications Manager(又称opManager)就是通过这种方式实现的。
使用这种方式,所监控Tomcat必须运行manager应用,缺省情况下,该应用总是运行在服务器中的。
增加manager角色用户
访问manager应用的用户的角色权限必须是 manager.
修改<TOMCAT_HOME>/conf目录下的tomcat-users.xml文件,在<tomcat-users>节点下添加一个user节点,即可创建一个用户。
Tomcat版本不同配置也有差异,5.x和6.x创建的用户角色应为manager,7.x创建的用户角色为manager-jmx,举例如下:
1、在5.x和6.x中创建一个manager角色的用户,用户名为admin,密码为chenfeng:
<user username="admin" password="chenfeng" roles="manager"/>
2、在7.x中创建一个manager角色的用户,用户名为admin,密码为chenfeng:
<user username="admin" password="chenfeng" roles="manager-jmx,manager-script,manager-status"/>
修改配置后,需要重新启动 Tomcat 服务器。
连接manager时将用户名/密码指定为admin/chenfeng
通过浏览器访问JMX Proxy Servlet
详见官方说明文档:
http://tomcat.apache.org/tomcat-6.0-doc/manager-howto.html#Using_the_JMX_Proxy_Servlet
What is JMX Proxy Servlet
The JMX Proxy Servlet is a lightweight proxy to get and set the tomcat internals. (Or any class that has been exposed via an MBean) Its usage is not very user friendly but the UI is extremely help for integrating command line scripts for monitoring and changing the internals of tomcat. You can do two things with the proxy: get information and set information. For you to really understand the JMX Proxy Servlet, you should have a general understanding of JMX. If you don't know what JMX is, then prepare to be confused.
JMX Query command
This takes the form: http://webserver/manager/jmxproxy/?qry=STUFF Where STUFF is the JMX query you wish to perform. For example, here are some queries you might wish to run: ◆ qry=*%3Atype%3DRequestProcessor%2C* --> type=RequestProcessorwhich will locate all workers which can process requests and report their state. ◆ qry=*%3Aj2eeType=Servlet%2c* --> j2eeType=Servletwhich return all loaded servlets. ◆ qry=Catalina%3Atype%3DEnvironment%2Cresourcetype%3DGlobal%2Cname%3DsimpleValue --> Catalina:type=Environment,resourcetype=Global,name=simpleValuewhich look for a specific MBean by the given name. You'll need to experiment with this to really understand its capabilites. If you provide no qry parameter, then all of the MBeans will be displayed. We really recommend looking at the tomcat source code and understand the JMX spec to get a better understanding of all the queries you may run.
通过浏览器访问http://localhost:8080/manager/jmxproxy ,输入用户名密码,然后就可以看到返回了所有的监控信息
添加查询参数,返回特定的监控信息:
例如:
http://localhost:8080/manager/jmxproxy?qry=*%3Atype%3DRequestProcessor%2C*
其中 *%3Atype%3DRequestProcessor%2C* 其实就是 *:type=RequestProcessor,*
又如:
http://localhost:8080/manager/jmxproxy?qry=*%3Aj2eeType%3DWebModule%2Cname%3D//localhost/ajaxrpc%2C*
在代码中访问JMX Proxy Servlet
通过浏览器访问JMX Proxy Servlet需要输入用户名密码,所以通过Java访问JMX Proxy Servlet的URL也需要授权访问: URL url = new URL("http://localhost:8080/manager/jmxproxy?qry=*%3Atype%3DManager%2C*");
URLConnection conn = (URLConnection) url.openConnection(); // URL授权访问 -- Begin String password = "admin:chenfeng"; // manager角色的用户 String encodedPassword = new BASE64Encoder().encode(password.getBytes()); conn.setRequestProperty("Authorization", "Basic " + encodedPassword); // URL授权访问 -- End InputStream is = conn.getInputStream(); BufferedReader bufreader = new BufferedReader(new InputStreamReader(is)); String line = null; while ((line = bufreader.readLine()) != null) { System.out.println(line); }
几个具体的例子
下面展示两个例子,一个是采集服务器基本信息,一个是采集Web应用列表信息,注意Tomcat 7.x和Tomcat 5.x、6.x之间存在很大的区别。
◆ 采集服务器基本信息
通过serverinfo命令查看服务器基本信息
http://localhost:8080/manager/serverinfo
Tomcat 7.x的查询URL有变化:
http://localhost:8080/manager/text/serverinfo
返回信息:
OK - Server info Tomcat Version: Apache Tomcat/7.0.11 OS Name: Windows Vista OS Version: 6.1 OS Architecture: x86 JVM Version: 1.6.0_13-b03 JVM Vendor: Sun Microsystems Inc.
◆ 采集Web应用列表信息
通过list命令查看Web应用列表和会话数信息
http://localhost:8080/manager/list
Tomcat 7.x的查询URL有变化:
http://localhost:8080/manager/text/list
返回信息:
OK - Listed applications for virtual host localhost /:running:0:ROOT /manager:running:1:manager /docs:running:0:docs /examples:running:0:examples /host-manager:running:0:host-manager
方案二、使用JMX 接口开发监控程序
Tomcat激活JMX远程配置
① 先修改Tomcat的启动脚本,window下tomcat的bin/catalina.bat(linux为catalina.sh),添加以下内 容,8999是jmxremote使用的端口号,第二个false表示不需要鉴权:
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
② 上面的配置是不需要鉴权的,如果需要鉴权则添加的内容为:
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了。
③ 重新启动Tomcat,在Windows命令行输入“netstat -a”查看配置的端口号是否已打开,如果打开,说明上面的配置成功了。
④ 使用jconsole测试JMX。
运行$JAVA_HOME/bin目录下的jconsole.exe,打开J2SE监视和管理控制台,然后建立连接,如 果是本地的Tomcat则直接选择然后点击连接,如果是远程的,则进入远程选项卡,填写地址、端口号、用户名、口令即可连接。Mbean属性页中给出了相 应的数据,Catalina中是tomcat的,java.lang是jvm的。对于加粗的黑体属性值,需双击一下才可看内容。
使用JMX监控Tomcat示例代码:
String jmxURL = "service:jmx:rmi:///jndi/rmi://192.168.10.93:8999/jmxrmi"; JMXServiceURL serviceURL = new JMXServiceURL(jmxURL); Map map = new HashMap(); // 用户名密码,在jmxremote.password文件中查看 String[] credentials = new String[] { "monitorRole", "tomcat" }; map.put("jmx.remote.credentials", credentials); JMXConnector connector = JMXConnectorFactory.connect(serviceURL, map); MBeanServerConnection mbsc = connector.getMBeanServerConnection(); // 端口最好是动态取得 ObjectName threadObjName = new ObjectName("Catalina:type=ThreadPool,name=http-8080"); MBeanInfo mbInfo = mbsc.getMBeanInfo(threadObjName); // tomcat的线程数对应的属性值 String attrName = "currentThreadCount"; MBeanAttributeInfo[] mbAttributes = mbInfo.getAttributes(); System.out.println("currentThreadCount:" + mbsc.getAttribute(threadObjName, attrName));
完整的示例代码文件:
import java.lang.management.MemoryUsage; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Formatter; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.management.MBeanAttributeInfo; import javax.management.MBeanInfo; import javax.management.MBeanServerConnection; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.openmbean.CompositeDataSupport; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; /** * 使用JMX监控Tomcat示例 * * @author 陳峰 */ public class JMXTest { /** * @param args */ public static void main(String[] args) { try { String jmxURL = "service:jmx:rmi:///jndi/rmi://127.0.0.1:8999/jmxrmi"; JMXServiceURL serviceURL = new JMXServiceURL(jmxURL); Map map = new HashMap(); String[] credentials = new String[] { "monitorRole", "tomcat" }; map.put("jmx.remote.credentials", credentials); JMXConnector connector = JMXConnectorFactory.connect(serviceURL, map); MBeanServerConnection mbsc = connector.getMBeanServerConnection(); // 端口最好是动态取得 ObjectName threadObjName = new ObjectName( "Catalina:type=ThreadPool,name=http-8080"); MBeanInfo mbInfo = mbsc.getMBeanInfo(threadObjName); String attrName = "currentThreadCount";// tomcat的线程数对应的属性值 MBeanAttributeInfo[] mbAttributes = mbInfo.getAttributes(); System.out.println("currentThreadCount:" + mbsc.getAttribute(threadObjName, attrName)); // heap for (int j = 0; j < mbsc.getDomains().length; j++) { System.out.println("###########" + mbsc.getDomains()[j]); } Set MBeanset = mbsc.queryMBeans(null, null); System.out.println("MBeanset.size() : " + MBeanset.size()); Iterator MBeansetIterator = MBeanset.iterator(); while (MBeansetIterator.hasNext()) { ObjectInstance objectInstance = (ObjectInstance) MBeansetIterator .next(); ObjectName objectName = objectInstance.getObjectName(); String canonicalName = objectName.getCanonicalName(); System.out.println("canonicalName : " + canonicalName); if (canonicalName .equals("Catalina:host=localhost,type=Cluster")) { // Get details of cluster MBeans System.out.println("Cluster MBeans Details:"); System.out .println("========================================="); // getMBeansDetails(canonicalName); String canonicalKeyPropList = objectName .getCanonicalKeyPropertyListString(); } } // ------------------------- system ---------------------- ObjectName runtimeObjName = new ObjectName("java.lang:type=Runtime"); System.out.println("厂商:" + (String) mbsc.getAttribute(runtimeObjName, "VmVendor")); System.out.println("程序:" + (String) mbsc.getAttribute(runtimeObjName, "VmName")); System.out.println("版本:" + (String) mbsc.getAttribute(runtimeObjName, "VmVersion")); Date starttime = new Date((Long) mbsc.getAttribute(runtimeObjName, "StartTime")); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("启动时间:" + df.format(starttime)); Long timespan = (Long) mbsc.getAttribute(runtimeObjName, "Uptime"); System.out.println("连续工作时间:" + JMXTest.formatTimeSpan(timespan)); // ------------------------ JVM ------------------------- // 堆使用率 ObjectName heapObjName = new ObjectName("java.lang:type=Memory"); MemoryUsage heapMemoryUsage = MemoryUsage .from((CompositeDataSupport) mbsc.getAttribute(heapObjName, "HeapMemoryUsage")); long maxMemory = heapMemoryUsage.getMax();// 堆最大 long commitMemory = heapMemoryUsage.getCommitted();// 堆当前分配 long usedMemory = heapMemoryUsage.getUsed(); System.out.println("heap:" + (double) usedMemory * 100 / commitMemory + "%");// 堆使用率 MemoryUsage nonheapMemoryUsage = MemoryUsage .from((CompositeDataSupport) mbsc.getAttribute(heapObjName, "NonHeapMemoryUsage")); long noncommitMemory = nonheapMemoryUsage.getCommitted(); long nonusedMemory = heapMemoryUsage.getUsed(); System.out.println("nonheap:" + (double) nonusedMemory * 100 / noncommitMemory + "%"); ObjectName permObjName = new ObjectName( "java.lang:type=MemoryPool,name=Perm Gen"); MemoryUsage permGenUsage = MemoryUsage .from((CompositeDataSupport) mbsc.getAttribute(permObjName, "Usage")); long committed = permGenUsage.getCommitted();// 持久堆大小 long used = heapMemoryUsage.getUsed();// System.out.println("perm gen:" + (double) used * 100 / committed + "%");// 持久堆使用率 // -------------------- Session --------------- ObjectName managerObjName = new ObjectName( "Catalina:type=Manager,*"); Set<ObjectName> s = mbsc.queryNames(managerObjName, null); for (ObjectName obj : s) { System.out.println("应用名:" + obj.getKeyProperty("path")); ObjectName objname = new ObjectName(obj.getCanonicalName()); System.out.println("最大会话数:" + mbsc.getAttribute(objname, "maxActiveSessions")); System.out.println("会话数:" + mbsc.getAttribute(objname, "activeSessions")); System.out.println("活动会话数:" + mbsc.getAttribute(objname, "sessionCounter")); } // ----------------- Thread Pool ---------------- ObjectName threadpoolObjName = new ObjectName( "Catalina:type=ThreadPool,*"); Set<ObjectName> s2 = mbsc.queryNames(threadpoolObjName, null); for (ObjectName obj : s2) { System.out.println("端口名:" + obj.getKeyProperty("name")); ObjectName objname = new ObjectName(obj.getCanonicalName()); System.out.println("最大线程数:" + mbsc.getAttribute(objname, "maxThreads")); System.out.println("当前线程数:" + mbsc.getAttribute(objname, "currentThreadCount")); System.out.println("繁忙线程数:" + mbsc.getAttribute(objname, "currentThreadsBusy")); } } catch (Exception e) { e.printStackTrace(); } } public static String formatTimeSpan(long span) { long minseconds = span % 1000; span = span / 1000; long seconds = span % 60; span = span / 60; long mins = span % 60; span = span / 60; long hours = span % 24; span = span / 24; long days = span; return (new Formatter()).format("%1$d天 %2$02d:%3$02d:%4$02d.%5$03d", days, hours, mins, seconds, minseconds).toString(); } }
相关推荐
基于Apache Tomcat的一站式Java应用服务器解决方案,包括系统整体架构设计以及监控运维管理平台Open Tomcat的构建。Open Tomcat通过松散耦合的方式对各应用节点进行管理,并集成了开源监控工具PsiProbe,同时为了...
另一个可能的解决方案是使用第三方监控工具,例如Nagios、Zabbix或Prometheus等,这些工具能提供更全面的系统监控,包括CPU使用率、内存占用、网络状态以及Tomcat特定的指标,如线程池状态和HTTP请求响应时间。...
Zabbix 运维监控平台解决方案 Zabbix 是一个企业级的开源分布式监控解决方案,它是一个基于 WEB 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。Zabbix 具备常见的商业监控软件所具备的功能,...
这个解决方案主要依赖于一个批处理脚本"监控tomcat.bat",以及可能需要的辅助工具如"curl.exe"。 首先,我们需要了解"监控tomcat.bat"的作用。这是一个Windows批处理文件,通常包含了检查Tomcat状态的命令和逻辑。...
Zabbix运维监控平台是一款强大的企业级开源分布式监控解决方案,它为各类组织提供了全面的系统、网络及应用监控功能。Zabbix能够24小时不间断地监控网站,确保在出现故障时,如服务器CPU负载过高、磁盘空间告急、...
Java Tomcat监控程序是用于确保Web应用程序持续稳定运行的...对于没有立即解决方案的线上问题,这种监控和报警机制可以作为有效的临时应对策略。如果您在使用过程中遇到任何问题,可以通过1076791016@qq.com进行咨询。
总结来说,"Tomcat服务器监控1.2版"是一个针对Java应用服务器Tomcat的监控解决方案,它可以帮助管理员在Windows和Linux环境中实时监控服务器状态,自动处理故障,提升服务的稳定性和效率。通过提供的源码,开发者...
【标题】"Tomcat监控脚本(支持Windows、Linux)...综合以上,一个全面的"Tomcat监控脚本--永不宕机"应该是一个集成了多种监控手段、异常处理策略和报警系统的自动化解决方案,能够跨平台地确保Tomcat服务器的稳定运行。
这个压缩包文件"基于Apache Tomcat的一站式Java应用服务器解决方案.zip"很可能包含了关于如何利用Tomcat搭建和管理Java应用程序的详细指南。 Apache Tomcat的核心功能包括: 1. **Servlet容器**:Tomcat的主要职责...
Zabbix是一款广泛应用的开源网络监控解决方案,它能够实时监控各种网络参数,确保服务器、应用和服务的稳定运行。本篇将深入探讨如何利用Zabbix来实现对Tomcat应用服务器的监控,并在Tomcat出现崩溃时自动进行重启,...
本解决方案监控的指标包括: * 性能数据:包括CPU、磁盘、网络、存储等关系系统正常运行的基本指标 * 端口状态:包括一般交换机或网络设备、端口启动状态、流量大小、网络状态 * 日志容监控:包括系统日志、应用...
总结来说,Tomcat监控工具是确保Java Web应用高效运行的关键,通过各种内置和第三方工具,我们可以全面地监控服务器状态,优化性能,提高系统的稳定性和可靠性。对于JVMStat这样的工具,深入了解其功能并有效利用,...
总结来说,Probe是一款强大的Tomcat监控解决方案,它提供了对数据库连接池、JVM内存、CPU以及其他系统性能的全面监控,帮助管理员优化Tomcat服务器的性能,预防和解决问题。"probe.war"文件是实现这个功能的核心组件...
JerryMouse的开发者和用户社区可以共享问题解决方案、提供技术支持和推动新功能的开发,这有助于项目的持续改进和长期发展。 7. **部署与配置** 鉴于其目标是改善用户交互,JerryMouse可能拥有更简洁的配置文件和...
标题“用LambdaProbe监控Tomcat”指的是在Java Web开发中,使用LambdaProbe工具来对Tomcat应用服务器进行实时性能监控的技术。LambdaProbe是一款强大的、基于Web的开源监控工具,适用于包括Tomcat在内的多种Java应用...
首先,WebLogic是由Oracle公司提供的一个全面的企业级Java应用服务器,它支持JMX来暴露管理接口,允许管理员远程监控服务器的状态、配置以及执行管理操作。通过JMX,你可以获取到WebLogic服务器的运行时信息,如JVM...
为了更好地管理和监控Tomcat的运行状态,开发者们开发了一系列的监控工具。这里我们要关注的是“Tomcat监控工具”,特别是“psi-probe”这一替代LambdaProbe的新版本。 【描述】:“替换LambdaProbe的psi-probe版本...
在这个场景中,shell脚本被用来组织和执行一系列步骤,包括登录远程服务器、传输文件、监控Tomcat服务的状态以及控制其启动和停止。 接下来是expect工具。Expect是一个用于自动化交互式进程的Tcl扩展,它可以模拟...
要监控Tomcat,首先需要修改`conf/tomcat-users.xml`,添加具有“manager”角色的用户,例如: ```xml <tomcat-users> </tomcat-users> ``` 重启Tomcat后,可以访问`...