java利用ManagementFactory获取tomcat的一些信息

         在上一篇中已经得到了jvm,os的一些信息,那如果是web项目,它在web容器中运行,那是否可以也得到一些信息进行监控呢?本篇写了个小例子,在tomcat6,jdk6下跑,利用ManagementFactory来获取tomcat的一些信息,至于其他web容器的获取请求,暂没做实验。。。

java利用ManagementFactory获取tomcat的一些信息_第1张图片

用jconsole监控,看看

java利用ManagementFactory获取tomcat的一些信息_第2张图片

      在catalina下,发现有很多信息。。。比如上图右侧圈出的,我们可以得到http-80这端口,也就是浏览器访问,可以得到总共有多少个请求访问过,接收了多少字节,发送了多少字节等信息。。。

下面贴个小例子源码

TestMonitorServlet.java

package com.fei.monitor;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 测试监控
 * @author weijianfei
 *
 */
public class TestMonitorServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doPost(request, response);
	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		StringBuffer sb = new StringBuffer();
		sb.append("

========tomcatInfo========


"); for(TomcatInformations info : TomcatInformations.buildTomcatInformationsList()){ sb.append(info).append("

"); } sb.append("

"); sb.append("

========threadInfo====


"); for(ThreadInformations t : ThreadInformations.buildThreadInformationsList()){ sb.append(t).append("

"); } //输出 outToClient(response, sb.toString()); } private void outToClient(HttpServletResponse response,String content){ response.setContentType("text/html"); response.setCharacterEncoding("utf-8"); PrintWriter writer; try { writer = response.getWriter(); writer.write(content); writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } }

MBeans.java

package com.fei.monitor;

import java.lang.management.ManagementFactory;
import java.util.Set;

import javax.management.JMException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

public class MBeans {

	private final MBeanServer mbeanServer;

	MBeans() {
		this(getPlatformMBeanServer());
	}

	private MBeans(MBeanServer mbeanServer) {
		super();
		this.mbeanServer = mbeanServer;
	}
	/**
	 * 获取MBeanServer
	 * @return
	 */
	static MBeanServer getPlatformMBeanServer() {
		return ManagementFactory.getPlatformMBeanServer();
	}
	/**
	 * 获取tomcat的线程池
	 * @return
	 * @throws MalformedObjectNameException
	 */
	Set getTomcatThreadPools() throws MalformedObjectNameException {
		return mbeanServer.queryNames(new ObjectName("*:type=ThreadPool,*"), null);
	}

	Set getTomcatGlobalRequestProcessors() throws MalformedObjectNameException {
		return mbeanServer.queryNames(new ObjectName("*:type=GlobalRequestProcessor,*"), null);
	}

	Object getAttribute(ObjectName name, String attribute) throws JMException {
		return mbeanServer.getAttribute(name, attribute);
	}
	
}
 
  


package com.fei.monitor;

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;

final public class PID {

	/**
	 * 获取当前进程id
	 * @return
	 */
	public static String getPID(){
		final RuntimeMXBean rtb = ManagementFactory.getRuntimeMXBean();
		//pid@host
		return rtb.getName().split("@")[0];
	}
}



TomcatInformations.java

package com.fei.monitor;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.JMException;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

final 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 THREAD_POOLS = new ArrayList();
	@SuppressWarnings("all")
	private static final List GLOBAL_REQUEST_PROCESSORS = new ArrayList();

	private final String name;
	private final int maxThreads;
	private final int currentThreadCount;
	private final int currentThreadsBusy;
	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 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 tomcatInformationsList = new ArrayList(
					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());
	}

	String getName() {
		return name;
	}

	int getMaxThreads() {
		return maxThreads;
	}

	int getCurrentThreadCount() {
		return currentThreadCount;
	}

	int getCurrentThreadsBusy() {
		return currentThreadsBusy;
	}

	long getBytesReceived() {
		return bytesReceived;
	}

	long getBytesSent() {
		return bytesSent;
	}

	int getRequestCount() {
		return requestCount;
	}

	int getErrorCount() {
		return errorCount;
	}

	long getProcessingTime() {
		return processingTime;
	}

	long getMaxTime() {
		return maxTime;
	}

	/** {@inheritDoc} */
	@Override
	public String toString() {
		return getClass().getSimpleName() + "[端口名name=" + getName() + ", 最大线程数maxThreads="
				+ getMaxThreads() + ",当前线程数 currentThreadCount=" + getCurrentThreadCount()
				+ ", 当前活动线程数currentThreadsBusy=" + getCurrentThreadsBusy() + ",接收字节数 bytesReceived="
				+ getBytesReceived() + ",发送字节数 bytesSent=" + getBytesSent() + ",请求数 requestCount="
				+ getRequestCount() + ", 错误数errorCount=" + getErrorCount() + ", 处理时间processingTime="
				+ getProcessingTime() + ", 最大处理时间maxTime=" + getMaxTime() + ']';
	}
}

ThreadInformations.java

package com.fei.monitor;

import java.io.Serializable;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;



class ThreadInformations implements Serializable {
	private static final long serialVersionUID = 3604281253550723654L;
	
	
	private final String name;//线程名称
	private final long id;//线程id
	private final int priority;//线程有限度
	private final boolean daemon;//是不是守护线程
	private final Thread.State state;//线程状态
	private final long cpuTimeMillis;//返回指定 ID 的线程的总 CPU 时间
	private final long userTimeMillis;//返回指定 ID 的线程在用户模式中执行的 CPU 时间
	private final boolean deadlocked;//是否死锁
	private final String globalThreadId;//全局线程id名称
	private final List stackTrace;

	private ThreadInformations(Thread thread, List stackTrace, long cpuTimeMillis,
			long userTimeMillis, boolean deadlocked, String hostAddress) {
		super();

		this.name = thread.getName();
		this.id = thread.getId();
		this.priority = thread.getPriority();
		this.daemon = thread.isDaemon();
		this.state = thread.getState();
		this.stackTrace = stackTrace;
		this.cpuTimeMillis = cpuTimeMillis;
		this.userTimeMillis = userTimeMillis;
		this.deadlocked = deadlocked;
		this.globalThreadId = buildGlobalThreadId(thread, hostAddress);
	}

	public static List buildThreadInformationsList() {
		final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
		final Map stackTraces = Thread.getAllStackTraces();
		final List	threads = new ArrayList(stackTraces.keySet());

		//虚拟机是否允许测量所有线程的cup时间
		 //isThreadCpuTimeSupported() 方法可用于确定 Java 虚拟机是否支持测量任何线程的 CPU 时间。
		//isCurrentThreadCpuTimeSupported() 方法可用于确定 Java 虚拟机是否支持测量当前线程的 CPU 时间。
		//支持任何线程 CPU 时间测量的 Java 虚拟机实现也支持当前线程的 CPU 时间测量
		final boolean cpuTimeEnabled = threadBean.isThreadCpuTimeSupported() && threadBean.isThreadCpuTimeEnabled();
		//获取所有死锁线程的id
		final long[] deadlockedThreads = getDeadlockedThreads(threadBean);
		final List threadInfosList = new ArrayList(threads.size());
		
		String hostAddress;
		try {
			hostAddress = InetAddress.getLocalHost().getHostAddress();
		} catch (UnknownHostException e) {
			hostAddress = "unknown";
		}
		
		for (final Thread thread : threads) {
			final StackTraceElement[] stackTraceElements = stackTraces.get(thread);
			final List stackTraceElementList = stackTraceElements == null ? null
					: new ArrayList(Arrays.asList(stackTraceElements));
			final long cpuTimeMillis;//返回指定 ID 的线程的总 CPU 时间(以毫微秒为单位)。
			final long userTimeMillis;//返回指定 ID 的线程在用户模式中执行的 CPU 时间(以毫微秒为单位)。
			if (cpuTimeEnabled) {
				cpuTimeMillis = threadBean.getThreadCpuTime(thread.getId()) / 1000000;
				userTimeMillis = threadBean.getThreadUserTime(thread.getId()) / 1000000;
			} else {
				cpuTimeMillis = -1;
				userTimeMillis = -1;
			}
			final boolean deadlocked = deadlockedThreads != null
					&& Arrays.binarySearch(deadlockedThreads, thread.getId()) >= 0;
			threadInfosList.add(new ThreadInformations(thread, stackTraceElementList,
					cpuTimeMillis, userTimeMillis, deadlocked, hostAddress));
		}
		return threadInfosList;
	}
	/**
	 * 获取所有的死锁线程id
	 * @param threadBean
	 * @return
	 */
	private static long[] getDeadlockedThreads(ThreadMXBean threadBean) {
		final long[] deadlockedThreads;
		//这方法是jdk1.6才提供的,简单点,在这就不做检查了,
		if (threadBean.isSynchronizerUsageSupported()) {
			deadlockedThreads = threadBean.findDeadlockedThreads();
		} else {
			deadlockedThreads = threadBean.findMonitorDeadlockedThreads();
		}
		if (deadlockedThreads != null) {
			Arrays.sort(deadlockedThreads);
		}
		return deadlockedThreads;
	}
	

	String getName() {
		return name;
	}

	long getId() {
		return id;
	}

	int getPriority() {
		return priority;
	}

	boolean isDaemon() {
		return daemon;
	}

	Thread.State getState() {
		return state;
	}

	List getStackTrace() {
		if (stackTrace != null) {
			return Collections.unmodifiableList(stackTrace);
		}
		return stackTrace;
	}

	String getExecutedMethod() {
		final List trace = stackTrace;
		if (trace != null && !trace.isEmpty()) {
			return trace.get(0).toString();
		}
		return "";
	}

	long getCpuTimeMillis() {
		return cpuTimeMillis;
	}

	long getUserTimeMillis() {
		return userTimeMillis;
	}

	boolean isDeadlocked() {
		return deadlocked;
	}

	String getGlobalThreadId() {
		return globalThreadId;
	}

	private static String buildGlobalThreadId(Thread thread, String hostAddress) {
		return PID.getPID() + '_' + hostAddress + '_' + thread.getId();
	}

	/** {@inheritDoc} */
	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append("[线程id=" + getId() 
				+",线程具体id(pid_host_tid)="+getGlobalThreadId()
				+ ",线程名称 name=" + getName() 
				+ ", 是否是守护线程daemon="+ isDaemon() 
				+ ",线程优先度 priority=" + getPriority() 
				+ ",是不是死锁 deadlocked=" + isDeadlocked()
				+ ", 运行状态state=" + getState() 
				+",线程使用CPU时间(毫秒)="+getCpuTimeMillis()
				+",线程在用户模式下使用CPU时间(毫秒)="+getUserTimeMillis()
		        +",执行的方法="+getExecutedMethod());
		if(getStackTrace() != null && !getStackTrace().isEmpty()){
			sb.append("
栈信息:"); for(StackTraceElement s : getStackTrace()){ sb.append("
").append(s.toString()); } } sb.append( ']'); return sb.toString(); } }
  http://127.0.0.1/testweb/TestMonitorServlet访问,查看结果

java利用ManagementFactory获取tomcat的一些信息_第3张图片



源码下载


你可能感兴趣的:(java监控学习,java,tomcat)