java利用ManagementFactory获取tomcat的一些信息
2015-11-27 16:15
603 查看
在上一篇中已经得到了jvm,os的一些信息,那如果是web项目,它在web容器中运行,那是否可以也得到一些信息进行监控呢?本篇写了个小例子,在tomcat6,jdk6下跑,利用ManagementFactory来获取tomcat的一些信息,至于其他web容器的获取请求,暂没做实验。。。
用jconsole监控,看看
在catalina下,发现有很多信息。。。比如上图右侧圈出的,我们可以得到http-80这端口,也就是浏览器访问,可以得到总共有多少个请求访问过,接收了多少字节,发送了多少字节等信息。。。
下面贴个小例子源码
TestMonitorServlet.java
MBeans.java
TomcatInformations.java
ThreadInformations.java
源码下载
用jconsole监控,看看
在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("<h3>========tomcatInfo========</h3><br/>"); for(TomcatInformations info : TomcatInformations.buildTomcatInformationsList()){ sb.append(info).append("<br/><br/>"); } sb.append("<br/><br/>"); sb.append("<h3>========threadInfo====</h3><br/>"); for(ThreadInformations t : ThreadInformations.buildThreadInformationsList()){ sb.append(t).append("<br/><br/>"); } //输出 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<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); } }
</pre><pre name="code" class="java">
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<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 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<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()); } 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<StackTraceElement> stackTrace; private ThreadInformations(Thread thread, List<StackTraceElement> 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<ThreadInformations> buildThreadInformationsList() { final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); final Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces(); final List<Thread> threads = new ArrayList<Thread>(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<ThreadInformations> threadInfosList = new ArrayList<ThreadInformations>(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<StackTraceElement> stackTraceElementList = stackTraceElements == null ? null : new ArrayList<StackTraceElement>(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<StackTraceElement> getStackTrace() { if (stackTrace != null) { return Collections.unmodifiableList(stackTrace); } return stackTrace; } String getExecutedMethod() { final List<StackTraceElement> 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("<br/>栈信息:"); for(StackTraceElement s : getStackTrace()){ sb.append("<br/>").append(s.toString()); } } sb.append( ']'); return sb.toString(); } }http://127.0.0.1/testweb/TestMonitorServlet访问,查看结果
源码下载
相关文章推荐
- Tomcat官方下载方法
- J2EE开发技术点5:Tomcat jdbc pool
- 阿里云服务器之hexo环境搭建
- tomcat性能调整,稳定一定访问量(转载)
- tomcat结合nginx使用小结
- Apache、tomcat、Nginx常用配置合集
- 一台机器上启动多个Tomcat
- SpringMVC异常总结:启动tomcat时出错,无法正取加载spring配置文件
- 解决centos7下tomcat启动正常,无法访问项目的问题
- centos7系统下安装配置jdk、tomcat教程
- Apache+Tomcat+mod_jk实现负载均衡
- 修改tomcat浏览器地址栏图标
- Apache+Tomcat+mod_jk实现负载均衡
- centos7系统下安装配置jdk、tomcat教程
- 解决centos7下tomcat启动正常,无法访问项目的问题
- 修改tomcat浏览器地址栏图标
- tomcat那些事
- tomcat那些事
- 创建 tomcat 服务的镜像
- Tomcat集群配置学习篇-----分布式应用