Tomcat扩展——监控

(转过来,源地址:http://www.jmatrix.org/notes/1067.html)

最近心血来潮,想是否可以通过增加一个tomcat的扩展,来持续收集tomcat服务器本身的性能信息,如线程池的各项数据,请求数等等,这样可以配合业务方面的监控,可以更方便的分析调整tomcat配置,以提供更好的服务。

这样也不需要每次通过连接jmx去观察数据,而且idc环境要开启jmx,还得涉及各种安全问题…….

Tomcat manager中StatusManagerServlet就是通过JMX提供了Tomcat服务的当前状态信息。我也会“抄袭”这里的代码来收集服务器数据。

要想定时的收集Tomcat的数据,需要在tomcat启动过程中,启一个定时任务去不停的收集服务信息,之后根据自己的需要,看是通过写日志方式保存,还是上报,抑或其它方式。

要做到不侵入tomcat本身源码,可以选择通过Listener的方式,实现一个自定义Listener,监听服务启动事件,启动数据采集任务,定时收集数据,如:

public class ServerInfoMonitorLifecycleListener implementsLifecycleListener {

      private ServerInfoCollection collect = new ServerInfoCollection();

      @Override
      public void lifecycleEvent(LifecycleEvent event ) {
          Lifecycle lifecycle = event .getLifecycle();
           if (Lifecycle.AFTER_START_EVENT .equals(event .getType())
                   && lifecycle instanceof Server) {
               collect.startMonitor();
          }
           if (Lifecycle.BEFORE_STOP_EVENT .equals(event .getType())
                   && lifecycle instanceof Server) {
               collect.stopMonitor();
          }
     }
}

这里监控的是Server的启动事件,需要注意,如果你想监控其它container,如host,context等,则配置listener的时候需要放到对应的container,大多数情况下,我们还是习惯配置在Server这一级别,确实在Server这一级别是最方便的。Tomcat本身的个别listener,想监听host,context等的事件是通过监听到Server事件的时候依次对server下面的host,context等添加listener。

有了定时收集tomcat数据的定时任务,下面就是数据的收集了。

首先得先获取需要的Mbean,如:

// Retrieve the MBean server
           mBeanServer = Registry.getRegistry( null , null ).getMBeanServer();

           try {
               // Query Thread Pools
               threadPools .clear();
              String onStr = "*:type=ThreadPool,*" ;
              ObjectName objectName = new ObjectName(onStr );
              Set set = mBeanServer .queryMBeans( objectName, null );
              Iterator iterator = set .iterator();
               while (iterator .hasNext()) {
                   ObjectInstance oi = iterator.next();
                    threadPools .addElement(oi .getObjectName());
              }

               // Query Global Request Processors
               globalRequestProcessors .clear();
               onStr = "*:type=GlobalRequestProcessor,*" ;
               objectName = new ObjectName( onStr);
               set = mBeanServer .queryMBeans(objectName , null );
               iterator = set.iterator();
               while (iterator .hasNext()) {
                   ObjectInstance oi = iterator.next();
                    globalRequestProcessors .addElement(oi .getObjectName());
              }

          } catch (Exception e ) {
               log.error( "init failed." , e );
          }

通过Mbean获取tomcat性能数据:

Enumeration enumeration = threadPools .elements();
               while (enumeration .hasMoreElements()) {
                   ObjectName objectName = enumeration .nextElement();
                   String name = objectName .getKeyProperty("name" );

                   ServerInfo serverInfo = new ServerInfo();
                    serverInfo .setMaxThreads((Integer) mBeanServer .getAttribute(
                              objectName , "maxThreads" ));
                    serverInfo .setCurrentThreadCount((Integer) mBeanServer
                             .getAttribute( objectName ,"currentThreadCount" ));
                    serverInfo .setCurrentThreadsBusy((Integer) mBeanServer
                             .getAttribute( objectName ,"currentThreadsBusy" ));
                    try {
                        Object value = mBeanServer .getAttribute(objectName ,
                                   "keepAliveCount" );
                         serverInfo .setKeepAliveCount((Integer) value );
                   } catch (Exception e ) {
                         // Ignore
                   }

                   ObjectName grpName = null ;
                   Enumeration reqEnumer =globalRequestProcessors
                             .elements();
                    while (reqEnumer .hasMoreElements()) {
                        ObjectName reqObjName = reqEnumer .nextElement();
                         if (name .equals(reqObjName .getKeyProperty( "name"))) {
                              grpName = reqObjName ;
                        }
                   }

                    if (grpName == null) {
                         return ;
                   }

                    serverInfo .setMaxTime((Long) mBeanServer .getAttribute(grpName ,
                              "maxTime" ));
                    serverInfo .setProcessingTime((Long) mBeanServer .getAttribute(
                              grpName, "processingTime" ));
                    serverInfo .setRequestCount((Integer) mBeanServer .getAttribute(
                              grpName, "requestCount" ));
                    serverInfo .setErrorCount((Integer) mBeanServer .getAttribute(
                              grpName, "errorCount" ));
                    serverInfo .setBytesReceived((Long) mBeanServer .getAttribute(
                              grpName, "bytesReceived" ));
                    serverInfo .setBytesSent((Long) mBeanServer .getAttribute(
                              grpName, "bytesSent" ));

                    store.storeInfo( serverInfo );

              }

在server.xml配置好自定义的listener,启动tomcat,便可以看到收集到的数据,如(这里为了测试,收集到的数据直接写日志):

ServerInfo:maxThreads:200,currentThreadCount:16,busyThreadCount:6,keepAliveCount:0,maxTime:6166,requestCount:57,errorCount:0,processTime:10380,bytesRec:0,bytesSend:238874

当然,还有很多其它的信息可以收集,看具体需要。

另外,还可以借助Value链条,编写自己的Value来上报请求处理时间,异常情况等等。

基础的代码可在github上看看:https://github.com/jjmatrix/tomcat-extension

相关的内容:

Tomcat源码走读1:从何开始

Tomcat源码走读2:启动过程

Tomcat源码走读5:请求处理

Tomcat源码走读——内存泄露检测

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-11 12:58:31

Tomcat扩展——监控的相关文章

tomcat 远程监控配置(JConsole)

 tomcat 远程监控配置     在生产环境下,使用top.vmstat等监控命令无法准确定位到单个tomcat应用服务的资源消耗情况:而JDK自带的JConsole具备图形化,可有效的监控服务状态: 通过本地主机配置JDK环境,服务段修改tomcat启动参数(即可实现无验证访问,也可实现远程账户密码访问) 部署环境:监控端:JDK9.0.1(win10 64 位) 服务段:tomcat-8.0.47(Centos 7.0  64位 ) 第一步:linux 系统下jdk安装 (1)安装wge

Windows下tomcat进程监控批处理程序

在Windows下tomcat进程监控批处理程序脚本如下: @echo off ::tomcat安装目录 set _tomcatDir=E:\myFiles\apache-tomcat-8.5.31 set _curlDir=E:\myFiles\apache-tomcat-8.5.31\curl set "httpcode=" ::访问tomcat cd /d %_curlDir% for /f "delims=" %%r in ('CURL.EXE -m 60

zabbix监控安装及实现对tomcat服务器监控

一.zabbix监控安装配置实现对本机的监控 监控端ip 192.168.1.11 被监控端ip 192.168.1.12 1.zabbix相关包的安装 1)zabbix的仓库源配置 [email protected]:~# wget https://repo.zabbix.com/zabbix/4.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_4.0-2+bionic_all.deb 2)安装zabbixx-release_4.0-2+b

实现zabbix对tomcat的监控

what-zabbix 优点: 1>开源,无软件成本投入 2>Server 对设备性能要求低 3>支持设备多,自带多种监控模板 4>支持分布式集中管理,有自动发现功能,可以实现自动化监控 5>开放式接口,扩展性强,插件编写容易 6>当监控的 item 比较多服务器队列比较大时可以采用被动状态,被监控客户端主动从server 端去下载需要监控的 item 然后取数据上传到 server 端.这种方式对服务器的负载比较小. 7>Api 的支持,方便与其他系统结合 缺点

web容器(02):tomcat配置监控

1.tomcat的目录结构 tomcat一般给Java应用的,apache一般给php应用的 bin文件夹(启动文件): 配置监听之类的内容是在catalina.sh中加 conf文件夹(配置文件): 2.server.xml配置文件说明 <Server port="8005" shutdown="SHUTDOWN"> → shutdown命令的端口号 <Connector port="8080" protocol="

tomcat进程监控

由于线上服务不知道在什么时候会挂掉,所以写了一个监控tomcat进程的脚本.如果该进程不存在时,去启动该tomcat进程. #!/bin/bash source /etc/profile source ~/.bash_profile # source /etc/profile ~/.bash_profile 这两句一定要加上,特别是在监控一些java进程的时候. pid=`ps -ef | grep app1 | grep -v "grep" |sed -n 1p | awk '{pr

JMX实现远程服务器Tomcat系统监控之三

前面两篇JMX远程监控Tomcat服务器是没配置密码的,下面介绍在Tomcat监控时配置用户密码. 具体Tomcat地址:http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html#Enabling_JMX_Remote Note: This syntax is for Microsoft Windows. The command has to be on the same line. It is wrapped to be more read

Tomcat 性能监控及调优

1.性能监控 方式1: /usr/local/tomcat7/conf/tomcat-users.xml 添加如下: <role rolename="manager-gui"/> <role rolename="manager-script"/> <role rolename="manager-jmx"/> <role rolename="manager-status"/> &l

Tomcat性能监控与调优

tomcat远程debug Tomcat是目前被应用得最多的一款Java Web服务器,很多人都会使用Tomcat来作为项目的服务器.也经常需要在开发的时候对Tomcat进行debug.在本地对Tomcat进行debug相信很多人都会,但如果需要对远程的Tomcat进行debug,相信有部分小伙伴还是没接触过的,而本小节将简单介绍一下如何对Tomcat进行远程debug. Tomcat远程debug是基于 JDWP 协议实现的,关于 JDWP 协议,可参考以下文档: https://www.ib