补0变为补null、单位最小Kb、服务器在线状态优化

This commit is contained in:
gaoyutao
2025-11-07 15:27:37 +08:00
parent ce95462d74
commit a5b304c809
3 changed files with 147 additions and 72 deletions
@@ -1,5 +1,6 @@
package com.ruoyi.common.core.utils;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
@@ -110,11 +111,17 @@ public class EchartsDataUtils {
// 初始化Y轴数据结构
dataExtractors.keySet().forEach(name ->
yData.put(name, new ArrayList<Object>()));
yData.put(name, new ArrayList<>()));
// 特殊处理:查找percentile95的固定值
Object fixedPercentile95Value = findFixedValueForPercentile95(sortedList, dataExtractors);
// 检测整个数据集中是否有真实数据
boolean hasRealData = checkHasRealData(sortedList, dataExtractors);
// 记录当前处理的时间点索引
int timeIndex = 0;
for (Date time : fullTimeSeries) {
// X轴数据
xAxisData.add(parseDateToStr(time));
@@ -132,12 +139,14 @@ public class EchartsDataUtils {
if (item != null) {
Object value = extractor.apply(item);
seriesData.add(value != null ? value : getDefaultValue(name, fixedPercentile95Value));
seriesData.add(value != null ? value : getDefaultValue(name, fixedPercentile95Value, timeIndex, hasRealData));
} else {
// 数据补全
seriesData.add(getDefaultValue(name, fixedPercentile95Value));
// 智能数据补全
seriesData.add(getDefaultValue(name, fixedPercentile95Value, timeIndex, hasRealData));
}
}
timeIndex++;
}
Map<String, Object> result = new HashMap<>();
@@ -152,6 +161,135 @@ public class EchartsDataUtils {
}
}
/**
* 检测整个数据集中是否有真实数据(非null)
*/
private static <T> boolean checkHasRealData(List<T> list, Map<String, Function<T, ?>> dataExtractors) {
for (T item : list) {
for (Map.Entry<String, Function<T, ?>> entry : dataExtractors.entrySet()) {
String name = entry.getKey();
Function<T, ?> extractor = entry.getValue();
Object value = extractor.apply(item);
if (value != null) {
return true; // 发现至少一个真实数据
}
}
}
return false; // 没有发现任何真实数据
}
/**
* 判断值是否为0(支持多种数值类型)
*/
private static boolean isZeroValue(Object value) {
if (value == null) return true;
if (value instanceof Number) {
return ((Number) value).doubleValue() == 0.0;
}
if (value instanceof BigDecimal) {
return ((BigDecimal) value).compareTo(BigDecimal.ZERO) == 0;
}
if (value instanceof String) {
try {
return new BigDecimal(value.toString()).compareTo(BigDecimal.ZERO) == 0;
} catch (Exception e) {
return false;
}
}
return false;
}
/**
* 智能获取默认值
* 策略:
* 1. 如果整个数据集有真实数据:所有缺失点都补null
* 2. 如果整个数据集没有真实数据:第一个点补0,其他点补null
* 3. percentile95特殊处理:使用固定值
*/
private static Object getDefaultValue(String metricName, Object fixedPercentile95Value,
int timeIndex, boolean hasRealData) {
// percentile95特殊处理
if ("percentile95".equals(metricName) && !fixedPercentile95Value.equals(0)) {
return fixedPercentile95Value;
}
// 智能补全策略
if (hasRealData) {
// 数据集中有真实数据:所有缺失点都补null
return null;
} else {
// 数据集中没有真实数据:第一个点补0,其他点补null
if (timeIndex == 0) {
return 0;
} else {
return null;
}
}
}
/**
* 创建空结果(智能补全策略)
*/
private static Map<String, Object> createEmptyResult(Set<String> dataNames, String startTime, String endTime) {
Map<String, Object> result = new HashMap<>();
try {
// 解析时间范围
Date startDate = parseStringToDate(startTime);
Date endDate = parseStringToDate(endTime);
if (startDate != null && endDate != null && !startDate.after(endDate)) {
// 使用默认时间间隔生成完整时间序列
long defaultInterval = 300000L; // 5分钟
List<Date> fullTimeSeries = generateTimeSeries(startDate, endDate, defaultInterval);
// 构建x轴数据
List<String> xAxisData = new ArrayList<>();
for (Date date : fullTimeSeries) {
xAxisData.add(parseDateToStr(date));
}
result.put("xData", xAxisData);
// 构建y轴数据(空数据集:第一个点补0,其他点补null)
Map<String, Object> yData = new LinkedHashMap<>();
int dataSize = xAxisData.size();
dataNames.forEach(name -> {
List<Object> seriesData = new ArrayList<>();
for (int i = 0; i < dataSize; i++) {
if (i == 0) {
// 第一个点补0
seriesData.add(0);
} else {
// 其他点补null
seriesData.add(null);
}
}
yData.put(name, seriesData);
});
result.put("yData", yData);
} else {
// 时间解析失败时返回空数据
result.put("xData", new ArrayList<>());
Map<String, Object> yData = new LinkedHashMap<>();
dataNames.forEach(name -> yData.put(name, new ArrayList<>()));
result.put("yData", yData);
}
} catch (Exception e) {
// 异常时返回空数据
result.put("xData", new ArrayList<>());
Map<String, Object> yData = new LinkedHashMap<>();
dataNames.forEach(name -> yData.put(name, new ArrayList<>()));
result.put("yData", yData);
}
return result;
}
/**
* 查找percentile95的固定值(第一个非零值)
*/
@@ -163,24 +301,13 @@ public class EchartsDataUtils {
Function<T, ?> extractor = dataExtractors.get("percentile95");
for (T item : list) {
Object value = extractor.apply(item);
if (value != null && !value.equals(0)) {
if (value != null) {
return value;
}
}
return 0;
}
/**
* 根据指标名称获取默认值
*/
private static Object getDefaultValue(String metricName, Object fixedPercentile95Value) {
if ("percentile95".equals(metricName) && !fixedPercentile95Value.equals(0)) {
return fixedPercentile95Value; // percentile95使用固定值
} else {
return 0; // 其他指标补0
}
}
/**
* 字符串转日期
*/
@@ -265,57 +392,4 @@ public class EchartsDataUtils {
return (timeMillis / interval) * interval;
}
/**
* 创建空结果(包含完整的时间序列)
*/
private static Map<String, Object> createEmptyResult(Set<String> dataNames, String startTime, String endTime) {
Map<String, Object> result = new HashMap<>();
try {
// 解析时间范围
Date startDate = parseStringToDate(startTime);
Date endDate = parseStringToDate(endTime);
if (startDate != null && endDate != null && !startDate.after(endDate)) {
// 使用默认时间间隔生成完整时间序列
long defaultInterval = 300000L; // 5分钟
List<Date> fullTimeSeries = generateTimeSeries(startDate, endDate, defaultInterval);
// 构建x轴数据
List<String> xAxisData = new ArrayList<>();
for (Date date : fullTimeSeries) {
xAxisData.add(parseDateToStr(date));
}
result.put("xData", xAxisData);
// 构建y轴数据(全部补0
Map<String, Object> yData = new LinkedHashMap<>();
int dataSize = xAxisData.size();
dataNames.forEach(name -> {
List<Object> zeroData = new ArrayList<>();
for (int i = 0; i < dataSize; i++) {
zeroData.add(0);
}
yData.put(name, zeroData);
});
result.put("yData", yData);
} else {
// 时间解析失败时返回空数据
result.put("xData", new ArrayList<>());
Map<String, Object> yData = new LinkedHashMap<>();
dataNames.forEach(name -> yData.put(name, new ArrayList<>()));
result.put("yData", yData);
}
} catch (Exception e) {
// 异常时返回空数据
result.put("xData", new ArrayList<>());
Map<String, Object> yData = new LinkedHashMap<>();
dataNames.forEach(name -> yData.put(name, new ArrayList<>()));
result.put("yData", yData);
}
return result;
}
}
@@ -329,7 +329,7 @@ public class SpeedUtils {
throws NoSuchFieldException, IllegalAccessException {
if (list == null || list.isEmpty()) {
return null;
return "Kb";
}
BigDecimal totalInSpeedBit = BigDecimal.ZERO;
@@ -706,12 +706,12 @@ public class MessageHandler {
interfaces.forEach(iface -> {
iface.setClientId(clientId);
iface.setCreateTime(createTime);
iface.setInSpeed(null);
iface.setOutSpeed(null);
// 总发送流量
iface.setTotalOutSpeed(dataProcessUtil.bytesToBits(iface.getOutSpeed()));
// 总接收流量
iface.setTotalInSpeed(dataProcessUtil.bytesToBits(iface.getInSpeed()));
iface.setInSpeed(null);
iface.setOutSpeed(null);
});
}
InitialBandwidthTraffic data = new InitialBandwidthTraffic();
@@ -886,6 +886,7 @@ public class MessageHandler {
RmResourceRegistrationRemote updateData = new RmResourceRegistrationRemote();
updateData.setClientId(message.getClientId());
updateData.setLogicalNodeId(heartbeat.getLogicalNode());
updateData.setOnlineStatus("1");
updateData.setAgentVersion(version);
updateData.setOnboardTime(DateUtils.getNowDate());
remoteRevenueConfigService.innerUpdateRegist(updateData, SecurityConstants.INNER);