關於tomcat繁忙執行緒數獲取
阿新 • • 發佈:2019-02-03
在某些情況下,我們需要對tomcat的繁忙執行緒數進行監控以滿足我們隊應用伺服器狀態資訊的把控。那麼我們該如何通過我們自定義的介面來獲得tomcat的繁忙執行緒數?
首先,我們應該想到tomcat本身是否為我們提供了類似的方法,博主在實際開發中拜讀了一遍tomcat的原始碼,的確也找到了獲取當前服務繁忙執行緒數的方法。但是它本身並未對外提供,並且使用的時候需要進行一些初始化操作。大家如果有興趣的話可以下載tomcat原始檔,找到org.apache.coyote.http11.AbstractHttp11Processor這個類,在process中有disableKeepAlive這個函式。進入函式檢視具體實現
我們可以看到tomcat本事是從執行緒池中取得活躍數,那麼我們也可以通過類似的辦法取得tomcat執行緒池中的活躍數。博主使用的jsp,大家可以對應改為後臺程式碼。
bean來解析執行緒池
public static class MBeans { private final MBeanServer mbeanServer; MBeans() { this(getPlatformMBeanServer()); } private MBeans(MBeanServer mbeanServer) { super(); this.mbeanServer = mbeanServer; } static MBeanServer getPlatformMBeanServer() { return ManagementFactory.getPlatformMBeanServer(); } Set<ObjectName> getTomcatThreadPools() throws MalformedObjectNameException { return mbeanServer.queryNames(new ObjectName("*:type=ThreadPool,*"), null); } Set<ObjectName> getTomcatGlobalRequestProcessors() throws MalformedObjectNameException { return mbeanServer.queryNames(new ObjectName("*:type=GlobalRequestProcessor,*"), null); } Object getAttribute(ObjectName name, String attribute) throws JMException { return mbeanServer.getAttribute(name, attribute); } }
然後用一個方法獲取資訊,這裡可以新增函式獲取到其他資訊,例如最大連線數等。
public static class TomcatInformations implements Serializable { private static final boolean TOMCAT_USED = System.getProperty("catalina.home") != null; private static final long serialVersionUID = -6145865427461051370L; @SuppressWarnings("all") private static final List<ObjectName> THREAD_POOLS = new ArrayList<ObjectName>(); @SuppressWarnings("all") private static final List<ObjectName> GLOBAL_REQUEST_PROCESSORS = new ArrayList<ObjectName>(); private final String name; private final int maxThreads; private final int currentThreadCount; private static int currentThreadsBusy=0; private final long bytesReceived; private final long bytesSent; private final int requestCount; private final int errorCount; private final long processingTime; private final long maxTime; private TomcatInformations(MBeans mBeans, ObjectName threadPool) throws JMException { super(); name = threadPool.getKeyProperty("name"); maxThreads = (Integer) mBeans.getAttribute(threadPool, "maxThreads"); currentThreadCount = (Integer) mBeans.getAttribute(threadPool, "currentThreadCount"); currentThreadsBusy = (Integer) mBeans.getAttribute(threadPool, "currentThreadsBusy"); ObjectName grp = null; for (final ObjectName globalRequestProcessor : GLOBAL_REQUEST_PROCESSORS) { if (name.equals(globalRequestProcessor.getKeyProperty("name"))) { grp = globalRequestProcessor; break; } } if (grp != null) { bytesReceived = (Long) mBeans.getAttribute(grp, "bytesReceived"); bytesSent = (Long) mBeans.getAttribute(grp, "bytesSent"); requestCount = (Integer) mBeans.getAttribute(grp, "requestCount"); errorCount = (Integer) mBeans.getAttribute(grp, "errorCount"); processingTime = (Long) mBeans.getAttribute(grp, "processingTime"); maxTime = (Long) mBeans.getAttribute(grp, "maxTime"); } else { bytesReceived = 0; bytesSent = 0; requestCount = 0; errorCount = 0; processingTime = 0; maxTime = 0; } } public static List<TomcatInformations> buildTomcatInformationsList() { if (!TOMCAT_USED) { return Collections.emptyList(); } try { synchronized (THREAD_POOLS) { if (THREAD_POOLS.isEmpty() || GLOBAL_REQUEST_PROCESSORS.isEmpty()) { initMBeans(); } } final MBeans mBeans = new MBeans(); final List<TomcatInformations> tomcatInformationsList = new ArrayList<TomcatInformations>( THREAD_POOLS.size()); for (final ObjectName threadPool : THREAD_POOLS) { tomcatInformationsList.add(new TomcatInformations(mBeans, threadPool)); } return tomcatInformationsList; } catch (final InstanceNotFoundException e) { return Collections.emptyList(); } catch (final AttributeNotFoundException e) { return Collections.emptyList(); } catch (final JMException e) { throw new IllegalStateException(e); } } private static void initMBeans() throws MalformedObjectNameException { final MBeans mBeans = new MBeans(); THREAD_POOLS.clear(); GLOBAL_REQUEST_PROCESSORS.clear(); THREAD_POOLS.addAll(mBeans.getTomcatThreadPools()); GLOBAL_REQUEST_PROCESSORS.addAll(mBeans.getTomcatGlobalRequestProcessors()); } public static long getCurrentThreadsBusy(){ buildTomcatInformationsList(); return currentThreadsBusy; } }
博主經過測試可以得到當前tomcat的活躍(繁忙)執行緒數,希望可以幫到大家。當然,tomcat也提供了管理功能,在管理功能裡面可以根據關鍵字獲得對應的數值。這也是一種獲取tomcat繁忙執行緒數的方式。