Tomcat擴展——監控
(轉過來,源地址:http://www.jmatrix.org/notes/1067.html)
近期心血來潮。想能否夠通過添加一個tomcat的擴展,來持續收集tomcatserver本身的性能信息。如線程池的各項數據,請求數等等,這樣能夠配合業務方面的監控,能夠更方便的分析調整tomcat配置,以提供更好的服務。
這樣也不須要每次通過連接jmx去觀察數據,並且idc環境要開啟jmx。還得涉及各種安全問題…….
Tomcat manager中StatusManagerServlet就是通過JMX提供了Tomcat服務的當前狀態信息。我也會“抄襲”這裏的代碼來收集server數據。
要想定時的收集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源代碼走讀——內存泄露檢測
Tomcat擴展——監控