Tomcat学习tomcat运行状态监控

编程

目前tomcat将运行的过程中的一些状态信息通过JMX的MBeanServer机制保存起来,所以目前的实现就是通过MBeanServer来获取数据就好,可以参考tomcat的StatusManagerServlet的实现逻辑。

    本篇博客只是简单的获取了一些数据进行展示

1、web.xml中配置如下

<!-- 查看tomcat中自身及每个war服务的运行情况 -->

<servlet>

<servlet-name>tomcat-monitor-info</servlet-name>

<servlet-class>com.tianjunwei.tomcat.servlet.MonitorInfoServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>tomcat-monitor-info</servlet-name>

<url-pattern>/tomcat_monitor_info</url-pattern>

</servlet-mapping>

2、实现源码如下:

public class MonitorInfoServlet  extends HttpServlet implements NotificationListener {

private static final long serialVersionUID = 1L;

protected static MBeanServer mBeanServer = null;

protected final Vector<ObjectName> protocolHandlers = new Vector<>();

protected final Vector<ObjectName> threadPools = new Vector<>();

protected final Vector<ObjectName> globalRequestProcessors = new Vector<>();

protected final Vector<ObjectName> requestProcessors = new Vector<>();

@Override

public void init() throws ServletException {

// Retrieve the MBean server

mBeanServer = Registry.getRegistry(null, null).getMBeanServer();

try {

// Query protocol handlers

String onStr = "*:type=ProtocolHandler,*";

ObjectName objectName = new ObjectName(onStr);

Set<ObjectInstance> set = mBeanServer.queryMBeans(objectName, null);

Iterator<ObjectInstance> iterator = set.iterator();

while (iterator.hasNext()) {

ObjectInstance oi = iterator.next();

protocolHandlers.addElement(oi.getObjectName());

}

// Query Thread Pools

onStr = "*:type=ThreadPool,*";

objectName = new ObjectName(onStr);

set = mBeanServer.queryMBeans(objectName, null);

iterator = set.iterator();

while (iterator.hasNext()) {

ObjectInstance oi = iterator.next();

threadPools.addElement(oi.getObjectName());

}

// Query Global Request Processors

onStr = "*:type=GlobalRequestProcessor,*";

objectName = new ObjectName(onStr);

set = mBeanServer.queryMBeans(objectName, null);

iterator = set.iterator();

while (iterator.hasNext()) {

ObjectInstance oi = iterator.next();

globalRequestProcessors.addElement(oi.getObjectName());

}

// Query Request Processors

onStr = "*:type=RequestProcessor,*";

objectName = new ObjectName(onStr);

set = mBeanServer.queryMBeans(objectName, null);

iterator = set.iterator();

while (iterator.hasNext()) {

ObjectInstance oi = iterator.next();

requestProcessors.addElement(oi.getObjectName());

}

// Register with MBean server

onStr = "JMImplementation:type=MBeanServerDelegate";

objectName = new ObjectName(onStr);

mBeanServer.addNotificationListener(objectName, this, null, null);

} catch (Exception e) {

e.printStackTrace();

}

}

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws IOException{

PrintWriter writer = response.getWriter();

Map<String, Object> dataMap = new HashMap<String,Object>();

dataMap.put("server", getServerData());

dataMap.put("os", getOsData());

dataMap.put("jvm", getJVMData());

dataMap.put("war", getWarData());

writer.write(JSON.toJSONString(dataMap));

writer.flush();

}

/**

* 获取操作系统及jvm相关的信息

*/

public static Map<String, Object> getServerData(){

Map<String, Object> serverMap =new HashMap<String, Object>();

serverMap.put("tomcat_version", ServerInfo.getServerInfo());

serverMap.put("jvm_version", System.getProperty("java.runtime.version"));

serverMap.put("jvm_vendor", System.getProperty("java.vm.vendor"));

serverMap.put("os_name", System.getProperty("os.name"));

serverMap.put("os_version", System.getProperty("os.version"));

serverMap.put("os_arch", System.getProperty("os.arch"));

try {

InetAddress address = InetAddress.getLocalHost();

serverMap.put("hostName", address.getHostName());

serverMap.put("hostAddress", address.getHostAddress());

} catch (UnknownHostException e) {

serverMap.put("hostName", "-");

serverMap.put("hostAddress", "-");

}

return serverMap;

}

/**

*

* 获取操作系统相关信息

*/

public static Map<String, Object> getOsData(){

Map<String, Object> osMap = new HashMap<String, Object>();

long[] result = new long[16];

boolean ok = false;

try {

String methodName = "info";

Class<?> paramTypes[] = new Class[1];

paramTypes[0] = result.getClass();

Object paramValues[] = new Object[1];

paramValues[0] = result;

Method method = Class.forName("org.apache.tomcat.jni.OS")

.getMethod(methodName, paramTypes);

method.invoke(null, paramValues);

ok = true;

} catch (Throwable t) {

t = ExceptionUtils.unwrapInvocationTargetException(t);

ExceptionUtils.handleThrowable(t);

}

if (ok) {

osMap.put(" Physical memory",formatSize(Long.valueOf(result[0]), true));

osMap.put(" Available memory: ",formatSize(Long.valueOf(result[1]), true));

osMap.put(" Total page file: ",formatSize(Long.valueOf(result[2]), true));

osMap.put(" Free page file: ",formatSize(Long.valueOf(result[3]), true));

osMap.put(" Memory load: ",Long.valueOf(result[6]));

osMap.put(" Process kernel time: ",formatTime(Long.valueOf(result[11] / 1000), true));

osMap.put(" Process user time: ",formatTime(Long.valueOf(result[12] / 1000), true));

}

return osMap;

}

public static Map<String, Object> getJVMData(){

Map<String, Object> jvmMap = new HashMap<String,Object>();

SortedMap<String, MemoryPoolMXBean> memoryPoolMBeans = new TreeMap<>();

for (MemoryPoolMXBean mbean: ManagementFactory.getMemoryPoolMXBeans()) {

String sortKey = mbean.getType() + ":" + mbean.getName();

memoryPoolMBeans.put(sortKey, mbean);

}

jvmMap.put("free_memory",Runtime.getRuntime().freeMemory());

jvmMap.put("total_memory",Runtime.getRuntime().totalMemory());

jvmMap.put("max_memory" , Runtime.getRuntime().maxMemory());

List<Map<String, Object>> memory_list = new ArrayList<Map<String, Object>>();

jvmMap.put("memory_pool", memory_list);

for (MemoryPoolMXBean memoryPoolMBean : memoryPoolMBeans.values()) {

MemoryUsage usage = memoryPoolMBean.getUsage();

Map<String, Object> useMap = new HashMap<String, Object>();

useMap.put("name",memoryPoolMBean.getName());

useMap.put("type",memoryPoolMBean.getType());

useMap.put("usageInit",usage.getInit());

useMap.put("usageCommitted",usage.getCommitted());

useMap.put("usageMax",usage.getMax());

useMap.put("usageUsed",usage.getUsed());

memory_list.add(useMap);

}

return jvmMap;

}

public static Map<String,Object> getWarData(){

Map<String,Object> dataMap=new HashMap<String, Object>();

try {

//堆使用

ObjectName heapObjName = new ObjectName("java.lang:type=Memory");

MemoryUsage heapMemoryUsage = MemoryUsage

.from((CompositeDataSupport) mBeanServer.getAttribute(heapObjName, "HeapMemoryUsage"));

dataMap.put("memoryUse", heapMemoryUsage.getUsed());

dataMap.put("memoryMax", heapMemoryUsage.getMax());

ObjectName runtimeObjName = new ObjectName("java.lang:type=Runtime");

RuntimeMXBean runtimeMXBean=ManagementFactory.getPlatformMXBean

(mBeanServer, RuntimeMXBean.class);

dataMap.put("uptime",runtimeMXBean.getUptime());

//永久代使用

ObjectName metaObjName = new ObjectName("java.lang:type=MemoryPool,name=Metaspace");

MemoryUsage metaMemoryUsage = MemoryUsage

.from((CompositeDataSupport) mBeanServer.getAttribute(metaObjName, "Usage"));

dataMap.put("metaspaceUse", (int)(metaMemoryUsage.getUsed()/(1024*1024)));

dataMap.put("metaspaceMax", (int)(metaMemoryUsage.getMax()/(1024*1024)));

//线程数连接数

ObjectName threadObjName = new ObjectName("Catalina:type=ThreadPool,name=*");

ObjectName threadMXBean=mBeanServer.queryNames(threadObjName, null).iterator().next();

dataMap.put("connectionCount", mBeanServer.getAttribute(threadMXBean, "connectionCount"));

dataMap.put("maxConnections", mBeanServer.getAttribute(threadMXBean, "maxConnections"));

dataMap.put("currentThreadCount", mBeanServer.getAttribute(threadMXBean, "currentThreadCount"));

dataMap.put("maxThreads", mBeanServer.getAttribute(threadMXBean, "maxThreads"));

//请求、错误请求、发送接收数据量

ObjectName grpObjName = new ObjectName("Catalina:type=GlobalRequestProcessor,*");

ObjectName requObjName=mBeanServer.queryNames(grpObjName, null).iterator().next();

dataMap.put("requestCount", mBeanServer.getAttribute(requObjName, "requestCount"));

dataMap.put("errorCount", mBeanServer.getAttribute(requObjName, "errorCount"));

//context

Host host = MyHostConfig.myHost;

List<Map<String,Object>> contexts=new ArrayList<Map<String,Object>>();

for(Container container:host.findChildren()){

Context context=(Context)container;

String name=context.getName().trim();

if("".equals(name)){

continue;

}

contexts.add(parseContext(context,mBeanServer));

}

dataMap.put("contexts", contexts);

} catch (Exception e) {

e.printStackTrace();

}

return dataMap;

}

private static Map<String,Object> parseContext(Context context,MBeanServer mbsc) throws Exception{

Map<String,Object> contextMap=new HashMap<String,Object>();

ObjectName objectName=context.getObjectName();

contextMap.put("name", context.getName().trim());

contextMap.put("state", context.getStateName());

/* contextMap.put("sessionTimeout", context.getSessionTimeout());*/

contextMap.put("requestCount", mbsc.getAttribute(objectName, "requestCount"));

contextMap.put("errorCount", mbsc.getAttribute(objectName, "errorCount"));

Manager manager=context.getManager();

Session[] sessions=manager.findSessions();

contextMap.put("sessionCount", sessions.length);

List<Map<String,Object>> sessionsInfo=new ArrayList<>();

for(int i=0;i<sessions.length;i++){

Map<String,Object> session=new HashMap<>();

session.put("sessionId", sessions[i].getId());

// session.put("viewIp", sessions[i].getSession().ge);

session.put("idleTIme", sessions[i].getIdleTime());

session.put("inactiveIntervalTime", sessions[i].getMaxInactiveInterval());

session.put("lastAcessTime", sessions[i].getLastAccessedTime());

sessionsInfo.add(session);

}

contextMap.put("sessions", sessionsInfo);

return contextMap;

}

public static Map<String,Object> getData(){

MBeanServer mBeanServer = Registry.getRegistry(null,null).getMBeanServer();

String onStr = "*:type=ThreadPool,*";

Map<String,Object> map = new HashMap<String,Object>();

try{

ObjectName objectName = new ObjectName(onStr);

Set set = mBeanServer.queryMBeans(objectName, null);

Vector<ObjectName> threadPool = new Vector<ObjectName>();

Iterator iterator = set.iterator();

while(iterator.hasNext()){

ObjectInstance oi = (ObjectInstance) iterator.next();

threadPool.addElement(oi.getObjectName());

}

Vector<ObjectName> globalRequestProcessors = new Vector<ObjectName>();

onStr = "*:type=GlobalRequestProcessor,*";

objectName = new ObjectName(onStr);

set.clear();

set = mBeanServer.queryMBeans(objectName, null);

iterator = set.iterator();

while(iterator.hasNext()){

ObjectInstance oi = (ObjectInstance) iterator.next();

globalRequestProcessors.addElement(oi.getObjectName());

}

Enumeration<ObjectName> enumeration = threadPool.elements();

while(enumeration.hasMoreElements()){

ObjectName objectName1 = enumeration.nextElement();

map.put("maxThread", mBeanServer.getAttribute(objectName1, "maxThreads"));

map.put("currentThreadCount", mBeanServer.getAttribute(objectName1, "currentThreadCount"));

map.put("connectionCount", mBeanServer.getAttribute(objectName1, "connectionCount"));

map.put("maxConnections", mBeanServer.getAttribute(objectName1, "maxConnections"));

}

Enumeration<ObjectName> reqEnume = globalRequestProcessors.elements();

while(reqEnume.hasMoreElements()){

ObjectName reqObjectName = reqEnume.nextElement();

map.put("processingTime", mBeanServer.getAttribute(reqObjectName, "processingTime"));

map.put("requestCount", mBeanServer.getAttribute(reqObjectName, "requestCount"));

map.put("errorCount", mBeanServer.getAttribute(reqObjectName, "errorCount"));

}

map.put("maxMemory", formatSize(Long.valueOf(Runtime.getRuntime().maxMemory()), true));

SortedMap<String, MemoryPoolMXBean> memoryPoolMBeans = new TreeMap<String, MemoryPoolMXBean>();

for (MemoryPoolMXBean mbean : ManagementFactory.getMemoryPoolMXBeans()) {

String sortKey = mbean.getType() + ":" + mbean.getName();

memoryPoolMBeans.put(sortKey, mbean);

}

Long usedMemory = 0l;

for (MemoryPoolMXBean memoryPoolMBean : memoryPoolMBeans.values()) {

MemoryUsage usage = memoryPoolMBean.getUsage();

usedMemory = usedMemory + Long.valueOf(usage.getUsed());

}

map.put("usedMemory", formatSize(usedMemory, true));

/*long connectionCount = (Long) mBeanServer.getAttribute(objectNameData, "connectionCount");

int maxConnections = (int) mBeanServer.getAttribute(objectNameData, "maxConnections");*/

}catch(Exception e){

e.printStackTrace();

}

return map;

}

public static long formatSize(Object obj, boolean mb) {

long bytes = -1L;

if (obj instanceof Long) {

bytes = ((Long) obj).longValue();

} else if (obj instanceof Integer) {

bytes = ((Integer) obj).intValue();

}

if (mb) {

StringBuilder buff = new StringBuilder();

if (bytes < 0) {

buff.append("-");

bytes = -bytes;

}

long mbytes = bytes / (1024 * 1024);

long rest = ((bytes - (mbytes * (1024 * 1024))) * 100) / (1024 * 1024);

buff.append(mbytes).append(".");

if (rest < 10) {

buff.append("0");

}

buff.append(rest);

double d = Double.parseDouble(buff.toString());

Long l = (long) d;

return l;

} else {

return (bytes / 1024);

}

}

public static String formatTime(Object obj) {

long time = -1L;

if (obj instanceof Long) {

time = ((Long) obj).longValue();

} else if (obj instanceof Integer) {

time = ((Integer) obj).intValue();

}

if (time > 1000 *1000) {

return ((((float) time ) / 1000) + " s");

} else if(time > 1000) {

return (time + " ms");

}else {

return ((((float) time ) / 1000) + " ms");

}

}

public static String formatTime(Object obj, boolean seconds) {

long time = -1L;

if (obj instanceof Long) {

time = ((Long) obj).longValue();

} else if (obj instanceof Integer) {

time = ((Integer) obj).intValue();

}

if (seconds) {

return ((((float) time ) / 1000) + " s");

} else {

return (time + " ms");

}

}

@Override

public void handleNotification(Notification notification,

java.lang.Object handback) {

if (notification instanceof MBeanServerNotification) {

ObjectName objectName =

((MBeanServerNotification) notification).getMBeanName();

if (notification.getType().equals

(MBeanServerNotification.REGISTRATION_NOTIFICATION)) {

String type = objectName.getKeyProperty("type");

if (type != null) {

if (type.equals("ProtocolHandler")) {

protocolHandlers.addElement(objectName);

} else if (type.equals("ThreadPool")) {

threadPools.addElement(objectName);

} else if (type.equals("GlobalRequestProcessor")) {

globalRequestProcessors.addElement(objectName);

} else if (type.equals("RequestProcessor")) {

requestProcessors.addElement(objectName);

}

}

} else if (notification.getType().equals

(MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {

String type = objectName.getKeyProperty("type");

if (type != null) {

if (type.equals("ProtocolHandler")) {

protocolHandlers.removeElement(objectName);

} else if (type.equals("ThreadPool")) {

threadPools.removeElement(objectName);

} else if (type.equals("GlobalRequestProcessor")) {

globalRequestProcessors.removeElement(objectName);

} else if (type.equals("RequestProcessor")) {

requestProcessors.removeElement(objectName);

}

}

String j2eeType = objectName.getKeyProperty("j2eeType");

if (j2eeType != null) {

}

}

}

}

}

3、获取的结果数据如下:

{

"jvm": {

"total_memory": 48758784,

"memory_pool": [{

"usageMax": 11010048,

"name": "PS Eden Space",

"usageUsed": 6111136,

"type": "HEAP",

"usageCommitted": 10485760,

"usageInit": 13107200

}, {

"usageMax": 35127296,

"name": "PS Old Gen",

"usageUsed": 19668376,

"type": "HEAP",

"usageCommitted": 35127296,

"usageInit": 35127296

}, {

"usageMax": 3145728,

"name": "PS Survivor Space",

"usageUsed": 1950184,

"type": "HEAP",

"usageCommitted": 3145728,

"usageInit": 2097152

}, {

"usageMax": 104857600,

"name": "Code Cache",

"usageUsed": 11987072,

"type": "NON_HEAP",

"usageCommitted": 12255232,

"usageInit": 2555904

}, {

"usageMax": 1073741824,

"name": "Compressed Class Space",

"usageUsed": 3185400,

"type": "NON_HEAP",

"usageCommitted": 3538944,

"usageInit": 0

}, {

"usageMax": -1,

"name": "Metaspace",

"usageUsed": 31663032,

"type": "NON_HEAP",

"usageCommitted": 32636928,

"usageInit": 0

}],

"free_memory": 21029088,

"max_memory": 48758784

},

"server": {

"hostName": "nb-hz20036325",

"tomcat_version": "Apache Tomcat/8.5.24",

"jvm_vendor": "Oracle Corporation",

"os_version": "6.1",

"os_arch": "amd64",

"os_name": "Windows 7",

"hostAddress": "10.13.80.12",

"jvm_version": "1.8.0_151-b12"

},

"os": {

" Free page file: ": 17006,

" Available memory: ": 4869,

" Physical memory": 12241,

" Process user time: ": "12.324 s",

" Total page file: ": 24481,

" Process kernel time: ": "7.254 s",

" Memory load: ": 60

},

"war": {

"requestCount": 112,

"connectionCount": 2,

"currentThreadCount": 10,

"memoryMax": 48758784,

"metaspaceUse": 30,

"contexts": [{

"requestCount": 0,

"sessions": [],

"sessionCount": 0,

"name": "/examples",

"state": "STARTED",

"errorCount": 0

}, {

"requestCount": 0,

"sessions": [],

"sessionCount": 0,

"name": "/host-manager",

"state": "STARTED",

"errorCount": 0

}, {

"requestCount": 48,

"sessions": [{

"inactiveIntervalTime": 1800,

"lastAcessTime": 1525247083747,

"sessionId": "11C58869BBF32D217EFF3F8B725982E6",

"idleTIme": 612935

}],

"sessionCount": 1,

"name": "/manager",

"state": "STARTED",

"errorCount": 1

}, {

"requestCount": 9,

"sessions": [],

"sessionCount": 0,

"name": "/docs",

"state": "STARTED",

"errorCount": 0

}, {

"requestCount": 2,

"sessions": [],

"sessionCount": 0,

"name": "/war_mointor",

"state": "STARTED",

"errorCount": 0

}],

"maxThreads": 200,

"errorCount": 4,

"memoryUse": 27729696,

"uptime": 11892453,

"metaspaceMax": 0,

"maxConnections": 10000

}

}

以上是 Tomcat学习tomcat运行状态监控 的全部内容, 来源链接: utcz.com/z/511042.html

回到顶部