您的位置:首页 > 运维架构 > Tomcat

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

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



用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访问,查看结果


源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: