监控缓存

This commit is contained in:
Arno 2019-08-21 19:34:13 +08:00
parent b2383f32ce
commit 02e5903f45
3 changed files with 219 additions and 217 deletions

View File

@ -4,6 +4,7 @@ import cn.jiangzeyin.common.JsonMessage;
import cn.jiangzeyin.controller.base.AbstractController;
import cn.keepbx.jpom.common.commander.AbstractSystemCommander;
import cn.keepbx.jpom.model.system.ProcessModel;
import cn.keepbx.jpom.system.TopManager;
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
@ -22,7 +23,7 @@ public class WelcomeController extends AbstractController {
@RequestMapping(value = "getTop", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public String getTop() {
JSONObject topInfo = AbstractSystemCommander.getInstance().getAllMonitor();
JSONObject topInfo = TopManager.getTopMonitor();
return JsonMessage.getString(200, "", topInfo);
}

View File

@ -1,7 +1,11 @@
package cn.keepbx.jpom.system;
import cn.hutool.cache.impl.CacheObj;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.cron.CronUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.pool.ThreadPoolService;
@ -13,11 +17,9 @@ import com.alibaba.fastjson.JSONObject;
import javax.websocket.Session;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@ -31,6 +33,8 @@ public class TopManager {
private static final Set<Session> SESSIONS = new HashSet<>();
private static final String CRON_ID = "topMonitor";
private static ExecutorService executorService = ThreadPoolService.newCachedThreadPool(TopManager.class);
private static final TimedCache<String, JSONObject> MONITOR_CACHE = new TimedCache<>(TimeUnit.MINUTES.toMillis(12), new LinkedHashMap<>());
/**
* 是否开启首页监听自动刷新
*/
@ -69,15 +73,9 @@ public class TopManager {
try {
JSONObject topInfo = AbstractSystemCommander.getInstance().getAllMonitor();
if (topInfo != null) {
DateTime date = DateUtil.date();
int hour = date.hour(true);
int minute = date.minute();
int day = date.dayOfMonth();
topInfo.put("hour", hour);
topInfo.put("minute", minute);
topInfo.put("day", day);
topInfo.put("second", date.second());
topInfo.put("time", DateUtil.format(date, "HH:mm:ss"));
String time = DateUtil.formatTime(DateUtil.date());
topInfo.put("time", time);
MONITOR_CACHE.put(time, topInfo);
send(topInfo.toString());
}
} catch (Exception e) {
@ -90,6 +88,66 @@ public class TopManager {
WATCH.set(true);
}
/**
* 缓存的监控信息
*
* @return 监控信息
*/
public static JSONObject getTopMonitor() {
Iterator<CacheObj<String, JSONObject>> cacheObjIterator = MONITOR_CACHE.cacheObjIterator();
String lastTime = "";
List<JSONObject> array = new ArrayList<>();
List<String> scale = new ArrayList<>();
while (cacheObjIterator.hasNext()) {
CacheObj<String, JSONObject> cacheObj = cacheObjIterator.next();
String key = cacheObj.getKey();
if (StrUtil.isNotEmpty(lastTime)) {
if (!key.equals(getLastTime(lastTime))) {
array.clear();
scale.clear();
}
}
lastTime = key;
scale.add(key);
JSONObject value = cacheObj.getValue();
array.add(value);
}
int count = 24;
if (array.size() > count) {
array = array.subList(array.size() - count - 1, array.size() - 1);
}
while (scale.size() < count) {
if (scale.size() == 0) {
DateTime date = DateUtil.date();
int second = date.second();
if (second <= 30 && second > 0) {
second = 30;
} else if (second > 30) {
second = 0;
date = date.offset(DateField.MINUTE, 1);
}
String format = DateUtil.format(date, "HH:mm");
String secondStr = ":" + second;
if (second < 10) {
secondStr = ":0" + second;
}
scale.add(format + secondStr);
}
String time = scale.get(scale.size() - 1);
String newTime = getLastTime(time);
scale.add(newTime);
}
JSONObject object = new JSONObject();
object.put("scale", scale);
object.put("series", array);
return object;
}
private static String getLastTime(String time) {
DateTime dateTime = DateUtil.parseTime(time);
DateTime newTime = dateTime.offsetNew(DateField.SECOND, 30);
return DateUtil.formatTime(newTime);
}
/**
* 发送首页进程列表信息

View File

@ -51,228 +51,171 @@
};
function loadSuccess() {
//
loadTopData();
loadTop();
//加载进程信息
loadProcessList();
//
tableRender(config);
linkSocket(true);
}
//加载病状图
function loadEcharts(xAxis, series) {
if (!series) {
return;
function loadTop() {
silentAjax({
url: './getTop',
success: function (data) {
if (200 === data.code && data.data) {
loadEchartsData(data.data);
//打开socket
linkSocket(true);
}
}
let option = {
title: {
text: '系统监控'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['cpu占用', '内存占用', '磁盘占用'],
right: '1%'
},
grid: {
left: '1%',
right: '2%',
bottom: '1%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: xAxis
},
calculable: true,
yAxis: {
type: 'value',
axisLabel: {
//设置y轴数值为%
formatter: '{value} %'
},
max: 100
},
series: series
};
if (!myEcharts) {
myEcharts = echarts.init(document.getElementById('echarts'));
});
}
function loadEchartsData(data) {
let series = data.series;
let cpuItem = {
name: 'cpu占用',
type: 'line',
data: [0],
//设置折线为曲线
smooth: true
};
let diskItem = {
name: '磁盘占用',
type: 'line',
data: [0],
smooth: true
};
let memoryItem = {
name: '内存占用',
type: 'line',
data: [0],
smooth: true
};
for (let i = 0; i < series.length; i++) {
let item = series[i];
if (i === 0) {
//删除默认0的数据
cpuItem.data.splice(0, 1);
diskItem.data.splice(0, 1);
memoryItem.data.splice(0, 1);
}
myEcharts.setOption(option);
cpuItem.data.push(parseFloat(item.cpu));
diskItem.data.push(parseFloat(item.disk));
memoryItem.data.push(parseFloat(item.memory));
}
let array = [cpuItem, memoryItem, diskItem];
loadEcharts(data.scale, array);
}
function linkSocket(status) {
if (!('WebSocket' in window)) {
layer.msg("不支持WebSocket");
return;
}
var url = getSocketHost() + "/console?userId=[[${session.user.getUserMd5Key()}]]&projectId=system&nodeId=[[${node.id}]]&type=console";
if (!ws) {
//拼接监控数据
function addTopData(topData) {
let option = myEcharts.getOption();
let series = option.series;
let xAxis = option.xAxis;
let xAxisData = xAxis[0].data;
let cpuItem = series[0];
let memoryItem = series[1];
let diskItem = series[2];
cpuItem.data.push(parseFloat(topData.cpu));
diskItem.data.push(parseFloat(topData.disk));
memoryItem.data.push(parseFloat(topData.memory));
//删除过时数据
if (cpuItem.data.length > xAxisData.length) {
cpuItem.data.splice(0, 1);
diskItem.data.splice(0, 1);
memoryItem.data.splice(0, 1);
xAxisData.splice(0, 1);
xAxisData.push(topData.time);
}
let newSeries = [cpuItem, memoryItem, diskItem];
loadEcharts(xAxisData, newSeries);
}
function linkSocket(status) {
if (!('WebSocket' in window)) {
layer.msg("不支持WebSocket");
return;
}
var url = getSocketHost() + "/console?userId=[[${session.user.getUserMd5Key()}]]&projectId=system&nodeId=[[${node.id}]]&type=console";
if (!ws) {
ws = new WebSocket(url);
}
if (status) {
if (ws.readyState !== 1 && ws.readyState !== 0) {
ws = new WebSocket(url);
}
if (status) {
if (ws.readyState !== 1 && ws.readyState !== 0) {
ws = new WebSocket(url);
}
ws.onopen = function () {
ws.send('{"op": "top", "projectInfo":{}}');
};
ws.onmessage = function (data) {
try {
if (data.data) {
var top = JSON.parse(data.data);
if (top.top) {
loadTopData(top);
}
if (top.processList) {
config.data = top.processList;
tableRender(config);
}
}
} catch (e) {
return;
}
};
ws.onerror = function (ev) {
console.log(ev);
layer.msg("socket 异常");
}
} else {
ws.close();
}
}
//保存监控数据
function loadTopData(topData) {
//默认刻度数量
let count = 24;
let dataTop = layui.data('top_[[${node.id}]]');
let top = [];
if (dataTop && dataTop.top) {
top = dataTop.top;
}
if (topData) {
top.push(topData);
}
let array = [];
let xAxis = [];
let cpuItem = {
name: 'cpu占用',
type: 'line',
data: [0],
//设置折线为曲线
smooth: true
ws.onopen = function () {
ws.send('{"op": "top", "projectInfo":{}}');
};
let diskItem = {
name: '磁盘占用',
type: 'line',
data: [0],
smooth: true
ws.onmessage = function (data) {
try {
if (data.data) {
var top = JSON.parse(data.data);
if (top.top) {
addTopData(top);
}
if (top.processList) {
config.data = top.processList;
tableRender(config);
}
}
} catch (e) {
return;
}
};
let memoryItem = {
name: '内存占用',
type: 'line',
data: [0],
smooth: true
};
let topLen = top.length;
for (let i = topLen - 1; i >= 0; i--) {
let item = top[i];
let len = array.length;
if (len >= count) {
break;
} else if (len > 0) {
let nextItem = array[0];
if (nextItem.day !== item.day || nextItem.time !== getNextMinute(item.hour, item.minute, item.second)) {
break;
}
}
if (i === topLen - 1) {
//删除默认0的数据
cpuItem.data.splice(0, 1);
diskItem.data.splice(0, 1);
memoryItem.data.splice(0, 1);
}
array.splice(0, 0, item);
cpuItem.data.splice(0, 0, parseFloat(item.cpu));
diskItem.data.splice(0, 0, parseFloat(item.disk));
memoryItem.data.splice(0, 0, parseFloat(item.memory));
xAxis.splice(0, 0, item.time);
ws.onerror = function (ev) {
console.log(ev);
layer.msg("socket 异常");
}
let len = xAxis.length;
if (len <= count) {
let item = array[array.length - 1];
if (!item) {
var myDate = new Date(); //实例一个时间对象;
item = {
hour: myDate.getHours(),
minute: myDate.getMinutes(),
second: myDate.getSeconds()
}
}
let hour = item.hour;
let minute = item.minute;
let second = item.second;
for (let i = 0; i < count - len; i++) {
if (i !== 0) {
second += 30;
if (second >= 60) {
second = 0;
minute += 1;
}
if (minute === 60) {
minute = 0;
hour += 1;
}
if (hour === 24) {
hour = 0;
}
}
xAxis.push(getNextMinute(hour, minute, second));
}
}
let series = [cpuItem, memoryItem, diskItem];
loadEcharts(xAxis, series);
layui.data('top_[[${node.id}]]', {
key: 'top',
value: array
});
} else {
ws.close();
}
}
//下半分钟 判断时间连续性
function getNextMinute(hour, minute, second) {
second += 30;
if (second <= 30 && second > 0) {
second = 30;
} else if (second >= 60) {
second = 0;
minute += 1;
} else {
second = 30;
//加载监控图
function loadEcharts(xAxis, series) {
if (!series) {
return;
}
if (minute === 60) {
hour += 1;
minute = 0;
let option = {
title: {
text: '系统监控'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['cpu占用', '内存占用', '磁盘占用'],
right: '1%'
},
grid: {
left: '1%',
right: '2%',
bottom: '1%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: xAxis
},
calculable: true,
yAxis: {
type: 'value',
axisLabel: {
//设置y轴数值为%
formatter: '{value} %'
},
max: 100
},
series: series
};
if (!myEcharts) {
myEcharts = echarts.init(document.getElementById('echarts'));
}
let hourStr = hour;
let minuteStr = minute;
let secondStr = second;
if (hour === 24) {
hour = 0;
}
if (hour < 10) {
hourStr = "0" + hour;
}
if (minute < 10) {
minuteStr = "0" + minute;
}
if (second < 10) {
secondStr = "0" + second;
}
return hourStr + ":" + minuteStr + ":" + secondStr;
myEcharts.setOption(option);
}
function loadProcessList() {