1. 程式人生 > >關於tomcat繁忙執行緒數獲取

關於tomcat繁忙執行緒數獲取

        在某些情況下,我們需要對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繁忙執行緒數的方式。