首页监听显示端口,重复加载进程锁

This commit is contained in:
jiangzeyin 2019-04-12 19:42:19 +08:00
parent 9f355ff12c
commit ff8fbebf8e
6 changed files with 85 additions and 40 deletions

View File

@ -12,6 +12,7 @@
6. 支持类似于Nginx二级代理配置(感谢@№譜樋)
7. 记录启动、重启、停止的操作人
8. Jpom 数据路径默认为程序运行的路径
9. 首页进程监听表格显示端口号
### 解决BUG、优化功能

View File

@ -49,20 +49,7 @@ public class WelcomeController extends BaseController {
@RequestMapping(value = "processList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String getProcessList() {
JSONArray array = null;
try {
if (AbstractCommander.OS_INFO.isLinux()) {
AbstractCommander instance = AbstractCommander.getInstance();
String head = instance.execSystemCommand("top -b -n 1 | head -7");
String s = instance.execSystemCommand("top -b -n 1 | grep java");
array = TopManager.formatLinuxTop(head + s);
} else {
String s = AbstractCommander.getInstance().execSystemCommand("tasklist /V | findstr java");
array = TopManager.formatWindowsProcess(s);
}
} catch (Exception e) {
DefaultSystemLog.ERROR().error(e.getMessage(), e);
}
JSONArray array = TopManager.getProcessList();
return JsonMessage.getString(200, "", array);
}
}

View File

@ -45,6 +45,12 @@ public class ProjectManageControl extends BaseController {
return "manage/projectInfo";
}
/**
* 获取正在运行的项目的端口和进程id
*
* @param ids ids
* @return json
*/
@RequestMapping(value = "getProjectPort", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String getProjectPort(String ids) {
@ -53,6 +59,7 @@ public class ProjectManageControl extends BaseController {
}
JSONArray jsonArray = JSONArray.parseArray(ids);
JSONObject jsonObject = new JSONObject();
JSONObject itemObj;
for (Object object : jsonArray) {
String item = object.toString();
int pid;
@ -65,8 +72,11 @@ public class ProjectManageControl extends BaseController {
if (pid <= 0) {
continue;
}
itemObj = new JSONObject();
int port = AbstractCommander.getInstance().getMainPort(pid);
jsonObject.put(item, port);
itemObj.put("port", port);
itemObj.put("pid", pid);
jsonObject.put(item, itemObj);
}
return JsonMessage.getString(200, "", jsonObject);
}

View File

@ -25,6 +25,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
/**
* top命令管理保证整个服务器只获取一个top命令
@ -39,6 +41,10 @@ public class TopManager {
private static CommandService commandService;
private static boolean watch = false;
private static ExecutorService executorService = ThreadPoolService.newCachedThreadPool(TopManager.class);
/**
* 锁定查看进程信息
*/
private static final AtomicBoolean ATOMIC_BOOLEAN = new AtomicBoolean(false);
/**
* 添加top 命令监听
@ -101,8 +107,22 @@ public class TopManager {
*/
private static void sendProcessList() {
executorService.execute(() -> {
JSONArray array = getProcessList();
if (array != null) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("processList", array);
send(jsonObject.toJSONString());
}
});
}
public static JSONArray getProcessList() {
if (ATOMIC_BOOLEAN.get()) {
return null;
}
JSONArray array;
try {
ATOMIC_BOOLEAN.set(true);
if (AbstractCommander.OS_INFO.isLinux()) {
AbstractCommander instance = AbstractCommander.getInstance();
String head = instance.execSystemCommand("top -b -n 1 | head -7");
@ -112,14 +132,28 @@ public class TopManager {
String s = AbstractCommander.getInstance().execSystemCommand("tasklist /V | findstr java");
array = formatWindowsProcess(s);
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("processList", array);
send(jsonObject.toJSONString());
} catch (Exception e) {
DefaultSystemLog.ERROR().error(e.getMessage(), e);
if (array != null) {
array.forEach(new Consumer<Object>() {
@Override
public void accept(Object o) {
JSONObject jsonObject = (JSONObject) o;
int pid = jsonObject.getIntValue("pid");
if (pid <= 0) {
return;
}
int port = AbstractCommander.getInstance().getMainPort(pid);
jsonObject.put("port", port);
}
});
}
return array;
} catch (Exception e) {
DefaultSystemLog.ERROR().error(e.getMessage(), e);
} finally {
ATOMIC_BOOLEAN.set(false);
}
return null;
}
/**
* 获取windows 监控

View File

@ -40,7 +40,7 @@
</script>
<script type="text/html" id="port_templ">
<span p-Id="{{d.id}}" title="端口:{{ getItemPort(d) }}">{{ getItemPort(d) }}</span>
<span p-Id="{{d.id}}" title="端口:{{ getItemPort(d) }} 进程id:{{ getItemPId(d) }}">{{ getItemPort(d) }}</span>
</script>
<script type="text/html" id="toolbarDemo">
@ -67,14 +67,26 @@
const apiWhere = {};
var cachePortInfo;
function getItemPort(data) {
function getCacheItemInfo(data, key) {
if (!data.status) {
return "";
}
if (!cachePortInfo) {
return "";
}
return cachePortInfo[data.id] || "";
if (!cachePortInfo[data.id]) {
return "";
}
return cachePortInfo[data.id][key] || "";
}
function getItemPort(data) {
return getCacheItemInfo(data, 'port');
}
function getItemPId(data) {
return getCacheItemInfo(data, 'pid');
}
function loadSuccess() {
@ -159,7 +171,7 @@
if (200 == data.code) {
cachePortInfo = data.data;
for (var key in data.data) {
$("span[p-Id='" + key + "']").text(data.data[key]).attr("title", "端口:" + data.data[key]);
$("span[p-Id='" + key + "']").text(data.data[key].port).attr("title", "端口:" + data.data[key].port + " 进程id:" + data.data[key].pid);
}
}
},

View File

@ -101,17 +101,18 @@
// height: 'full-52',
even: true,
cols: [[
{field: 'pid', title: '进程id', sort: true, width: '8%'},
{field: 'USER', title: '所有者', width: '12%'},
{field: 'PR', title: '优先级', width: '8%', sort: true},
{field: 'NI', title: 'nice值', width: '8%', sort: true},
{field: 'VIRT', title: '使用虚拟内存', width: '8%', sort: true},
{field: 'RES', title: '使用物理内存', width: '8%', sort: true},
{field: 'pid', title: '进程id', sort: true, width: '6%'},
{field: 'port', title: '端口', sort: true, width: '6%'},
{field: 'USER', title: '所有者', width: '8%'},
{field: 'PR', title: '优先级', width: '6%', sort: true},
{field: 'NI', title: 'nice值', width: '6%', sort: true},
{field: 'VIRT', title: '虚拟内存', width: '8%', sort: true},
{field: 'RES', title: '物理内存', width: '8%', sort: true},
{field: 'SHR', title: '共享内存', width: '8%', sort: true},
{field: 'S', title: '进程状态', width: '8%', sort: true},
{field: 'CPU', title: '占用CPU', width: '8%', sort: true},
{field: 'MEM', title: '占用物理内存', width: '8%', sort: true},
{field: 'TIME', title: '时间总计', width: '8%', sort: true},
{field: 'MEM', title: '物理内存', width: '8%', sort: true},
{field: 'TIME', title: '时间总计', sort: true},
{field: 'COMMAND', title: '进程名称'}
]],
loading: true,