线程列表

This commit is contained in:
Arno 2019-04-24 11:21:10 +08:00
parent 364effb1e8
commit 14a6371041
4 changed files with 119 additions and 6 deletions

View File

@ -12,6 +12,7 @@ import cn.keepbx.jpom.model.system.ProcessModel;
import cn.keepbx.jpom.system.AgentConfigBean;
import cn.keepbx.jpom.util.CommandUtil;
import cn.keepbx.jpom.util.JvmUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sun.tools.attach.VirtualMachine;
import org.springframework.http.MediaType;
@ -22,8 +23,11 @@ import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.math.BigDecimal;
import java.util.List;
@ -53,9 +57,60 @@ public class InternalController extends BaseAgentController {
//获取端口信息
List<NetstatModel> netstatModels = AbstractProjectCommander.getInstance().listNetstat(pid);
jsonObject.put("netstat", netstatModels);
JSONArray threadInfos = getThreadInfos(tag);
//获取jvm中的活动线程
jsonObject.put("threadInfos", threadInfos);
return JsonMessage.getString(200, "", jsonObject);
}
/**
* 获取jvm中的活动线程
*
* @param tag tag
* @return 活动线程
* @throws Exception Exception
*/
private JSONArray getThreadInfos(String tag) throws Exception {
VirtualMachine virtualMachine = JvmUtil.getVirtualMachine(tag);
ThreadMXBean threadMXBean = JvmUtil.getThreadMXBean(virtualMachine);
if (threadMXBean == null) {
return null;
}
ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
if (threadInfos == null || threadInfos.length <= 0) {
return null;
}
JSONArray array = new JSONArray();
JSONArray waitArray = new JSONArray();
for (ThreadInfo threadInfo : threadInfos) {
Thread.State threadState = threadInfo.getThreadState();
JSONObject object = new JSONObject();
object.put("id", threadInfo.getThreadId());
object.put("name", threadInfo.getThreadName());
object.put("status", threadState);
object.put("waitedCount", threadInfo.getWaitedCount());
object.put("waitedTime", threadInfo.getWaitedTime());
object.put("blockedCount", threadInfo.getBlockedCount());
object.put("blockedTime", threadInfo.getBlockedTime());
object.put("isInNative", threadInfo.isInNative());
object.put("isSuspended", threadInfo.isSuspended());
if (threadState == Thread.State.RUNNABLE || threadState == Thread.State.NEW) {
array.add(object);
if (array.size() == 10) {
return array;
}
} else if (threadState == Thread.State.WAITING) {
waitArray.add(object);
}
}
int size = array.size();
if (size < 10) {
List<Object> objects = waitArray.subList(0, 10 - size);
array.addAll(objects);
}
return array;
}
/**
* 获取jvm内存
*

View File

@ -19,6 +19,7 @@ import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.ThreadMXBean;
import java.net.URISyntaxException;
import java.util.*;
@ -67,6 +68,24 @@ public class JvmUtil {
return ManagementFactory.newPlatformMXBeanProxy(mBeanServerConnection, ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME, OperatingSystemMXBean.class);
}
/**
* 获取指定程序的线程信息
*
* @param virtualMachine VirtualMachine
* @return 没有运行或者获取数据
* @throws Exception 异常
* @see ThreadMXBean
*/
public static ThreadMXBean getThreadMXBean(VirtualMachine virtualMachine) throws Exception {
JMXServiceURL jmxServiceURL = getJMXServiceURL(virtualMachine);
if (jmxServiceURL == null) {
return null;
}
JMXConnector jmxConnector = JMXConnectorFactory.connect(jmxServiceURL, null);
MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();
return ManagementFactory.newPlatformMXBeanProxy(mBeanServerConnection, ManagementFactory.THREAD_MXBEAN_NAME, ThreadMXBean.class);
}
/**
* 获取jmx 服务对象如果没有加载则加载对应插件
*

View File

@ -102,6 +102,46 @@
</div>
#end
#if($data.threadInfos)
<div class="info">
<label> 线程列表</label>
<table class="layui-table" style="margin-top: 10px">
<thead>
<tr>
<th>线程id</th>
<th>线程名称</th>
<th>线程状态</th>
<th>唤醒次数</th>
<th>运行总时间(毫秒)</th>
<th>阻塞次数</th>
<th>阻塞总时间(毫秒)</th>
<th>本地线程</th>
<th>是否挂起</th>
</tr>
</thead>
<tbody>
#foreach($item in $data.threadInfos)
<tr>
<td>$item.id</td>
<td>$item.name</td>
<td>$item.status</td>
<td>$item.blockedCount</td>
<td>$item.blockedTime</td>
<td>$item.waitedCount</td>
<td>$item.waitedTime</td>
<td>#if($item.isInNative)
是 #else 否
#end</td>
<td>#if($item.isSuspended)
是 #else 否
#end</td>
</tr>
#end
</tbody>
</table>
</div>
#end
<div class="info">
<label>端口信息</label>
<table class="layui-table" style="margin-top: 10px">

View File

@ -185,12 +185,11 @@
layer.msg('请先运行程序!');
return;
}
layerOpen({
type: 2,
title: '内存',
shade: 0.8,
area: ['80%', '80%'],
content: 'internal?tag=' + data.id
var url = "/node/manage/internal?tag=" + data.id;
tabChange({
id: "ram_" + data.id,
url: url,
title: data.id + ' - 监控',
});
}
});