diff --git a/reisa-admin/reisaAdminSpring/pom.xml b/reisa-admin/reisaAdminSpring/pom.xml
index ce15028..fcf2cde 100644
--- a/reisa-admin/reisaAdminSpring/pom.xml
+++ b/reisa-admin/reisaAdminSpring/pom.xml
@@ -64,6 +64,23 @@
0.1.55
+
+
+ test
+
+ true
+
+
+ test
+
+
+
+ product
+
+ product
+
+
+
diff --git a/reisa-admin/reisaAdminSpring/src/main/java/org/ast/reisaadminspring/api/ApiServerV1.java b/reisa-admin/reisaAdminSpring/src/main/java/org/ast/reisaadminspring/api/ApiServerV1.java
index 15e1c09..ba4f9c4 100644
--- a/reisa-admin/reisaAdminSpring/src/main/java/org/ast/reisaadminspring/api/ApiServerV1.java
+++ b/reisa-admin/reisaAdminSpring/src/main/java/org/ast/reisaadminspring/api/ApiServerV1.java
@@ -20,6 +20,7 @@ import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Semaphore;
import java.util.stream.Collectors;
@RestController
@@ -71,14 +72,6 @@ public class ApiServerV1 {
}
}
}
- @GetMapping("/status/history/{ip}")
- public List getStatus(@PathVariable String ip, @RequestParam(defaultValue = "0", required = false) int limit) {
- List statuses = statusDao.findByHostOrderByTimestampDesc(ip);
- if (limit > 0) {
- return statuses.stream().limit(limit).collect(Collectors.toList());
- }
- return statuses;
- }
@GetMapping("/server")
public List getAllServers() {
@@ -138,4 +131,178 @@ public class ApiServerV1 {
public void deleteServer(@RequestBody Server server) {
serverDao.delete(server);
}
+
+ @GetMapping("/status/history/{ip}")
+ public List getStatus(@PathVariable String ip,
+ @RequestParam(defaultValue = "0000-00-00 00:00:00", required = false) String startDate,
+ @RequestParam(defaultValue = "9999-99-99 99:99:99", required = false) String endDate) {
+ System.out.println("getStatus: " + ip + "开始加载");
+ List statuses = statusDao.findByHostOrderByTimestampDesc(ip);
+ System.out.println("getStatus: " + ip + "加载完成");
+ // 时间范围过滤
+ LocalDateTime start = parseDateTime(startDate);
+ LocalDateTime end = parseDateTime(endDate);
+
+ List filteredStatuses = statuses.stream()
+ .filter(status -> status.getTimestamp() != null)
+ .filter(status -> !status.getTimestamp().isBefore(start))
+ .filter(status -> !status.getTimestamp().isAfter(end))
+ .collect(Collectors.toList());
+ // 数据优化 - 移除变化较小的数据点
+ List optimizedStatuses = optimizeStatusData(filteredStatuses);
+ System.out.println("getStatus: " + ip + "数据优化完成");
+ System.out.print(optimizedStatuses.size());
+ return optimizedStatuses;
+ }
+ @GetMapping("/status/history/all/{ips}")
+ public Map> getStatusIps(@PathVariable String ips,
+ @RequestParam(defaultValue = "0000-00-00 00:00:00", required = false) String startDate,
+ @RequestParam(defaultValue = "9999-99-99 99:99:99", required = false) String endDate) {
+ List ipList = Arrays.asList(ips.split(","));
+ Map> optimizedStatuses = new ConcurrentHashMap<>();
+
+ // 限制并发数量,避免数据库连接耗尽
+ Semaphore semaphore = new Semaphore(10); // 最多同时处理10个IP
+
+ List> futures = ipList.stream()
+ .map(ip -> CompletableFuture.runAsync(() -> {
+ try {
+ semaphore.acquire(); // 获取许可
+ List statuses = statusDao.findByHostOrderByTimestampDesc(ip);
+
+ // 时间范围过滤
+ LocalDateTime start = parseDateTime(startDate);
+ LocalDateTime end = parseDateTime(endDate);
+
+ List filteredStatuses = statuses.stream()
+ .filter(status -> status.getTimestamp() != null)
+ .filter(status -> !status.getTimestamp().isBefore(start))
+ .filter(status -> !status.getTimestamp().isAfter(end))
+ .collect(Collectors.toList());
+
+ // 数据优化 - 移除变化较小的数据点
+ List optimizedStatuse = optimizeStatusData(filteredStatuses);
+ optimizedStatuses.put(ip, optimizedStatuse);
+ } catch (Exception e) {
+ log.error("Error processing status for IP: {}", ip, e);
+ optimizedStatuses.put(ip, new ArrayList<>());
+ } finally {
+ semaphore.release(); // 释放许可
+ }
+ }))
+ .collect(Collectors.toList());
+
+ // 等待所有任务完成
+ CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
+
+ return optimizedStatuses;
+ }
+
+ private LocalDateTime parseDateTime(String dateTimeStr) {
+ try {
+ // 处理默认值情况
+ if ("0000-00-00 00:00:00".equals(dateTimeStr) || "9999-99-99 99:99:99".equals(dateTimeStr)) {
+ return "0000-00-00 00:00:00".equals(dateTimeStr) ?
+ LocalDateTime.MIN : LocalDateTime.MAX;
+ }
+ return LocalDateTime.parse(dateTimeStr.replace(" ", "T"));
+ } catch (Exception e) {
+ return LocalDateTime.now();
+ }
+ }
+
+ private List optimizeStatusData(List statuses) {
+ if (statuses.size() <= 2) {
+ return statuses; // 数据点太少无需优化
+ }
+
+ List result = new ArrayList<>();
+ result.add(statuses.get(0)); // 始终保留第一个点
+
+ // 计算CPU和内存使用率变化的阈值(基于整体数据计算)
+ double cpuThreshold = calculateThreshold(statuses, Status::getCpuUsagePercent);
+ double memoryThreshold = calculateThreshold(statuses, Status::getMemoryUsagePercent);
+
+ // 设置最小阈值,避免过度优化
+ cpuThreshold = Math.max(cpuThreshold, 0.5); // 最小0.5%
+ memoryThreshold = Math.max(memoryThreshold, 0.5); // 最小0.5%
+
+ Status previousStatus = statuses.get(0);
+
+ for (int i = 1; i < statuses.size() - 1; i++) {
+ Status current = statuses.get(i);
+
+ // 检查CPU或内存使用率是否有显著变化
+ boolean significantChange =
+ hasSignificantChange(previousStatus, current, cpuThreshold, memoryThreshold);
+
+ if (significantChange) {
+ result.add(current);
+ previousStatus = current;
+ }
+ }
+
+ // 始终保留最后一个点
+ if (!statuses.isEmpty() && !result.contains(statuses.get(statuses.size() - 1))) {
+ result.add(statuses.get(statuses.size() - 1));
+ }
+
+ return result;
+ }
+
+ private boolean hasSignificantChange(Status prev, Status curr,
+ double cpuThreshold, double memoryThreshold) {
+ Double prevCpu = prev.getCpuUsagePercent();
+ Double currCpu = curr.getCpuUsagePercent();
+ Double prevMem = prev.getMemoryUsagePercent();
+ Double currMem = curr.getMemoryUsagePercent();
+
+ // 如果任一值为空,则认为有变化
+ if (prevCpu == null || currCpu == null || prevMem == null || currMem == null) {
+ return true;
+ }
+
+ // 检查变化是否超过阈值
+ return Math.abs(currCpu - prevCpu) >= cpuThreshold ||
+ Math.abs(currMem - prevMem) >= memoryThreshold;
+ }
+
+ // 在Status类中添加辅助方法获取使用率数值
+ private static class StatusExtensions {
+ public static Double getCpuUsagePercent(Status status) {
+ return status.getCpuInfo() != null ? status.getCpuInfo().getUsagePercent() : null;
+ }
+
+ public static Double getMemoryUsagePercent(Status status) {
+ return status.getMemoryInfo() != null ? status.getMemoryInfo().getUsagePercent() : null;
+ }
+ }
+
+ private double calculateThreshold(List statuses, java.util.function.Function getter) {
+ // 收集所有有效数值
+ List values = statuses.stream()
+ .map(getter)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+
+ if (values.size() < 2) {
+ return 0.0;
+ }
+
+ // 计算相邻数值间的差值
+ List differences = new ArrayList<>();
+ for (int i = 1; i < values.size(); i++) {
+ differences.add(Math.abs(values.get(i) - values.get(i-1)));
+ }
+
+ // 计算平均差值作为阈值基础
+ double averageDifference = differences.stream()
+ .mapToDouble(Double::doubleValue)
+ .average()
+ .orElse(0.0);
+
+ // 返回平均差值的一半作为阈值,这样可以过滤掉较小的变化
+ return averageDifference / 2;
+ }
+
}
diff --git a/reisa-admin/reisaAdminSpring/src/main/java/org/ast/reisaadminspring/been/Status.java b/reisa-admin/reisaAdminSpring/src/main/java/org/ast/reisaadminspring/been/Status.java
index 1f52c25..97eac02 100644
--- a/reisa-admin/reisaAdminSpring/src/main/java/org/ast/reisaadminspring/been/Status.java
+++ b/reisa-admin/reisaAdminSpring/src/main/java/org/ast/reisaadminspring/been/Status.java
@@ -147,6 +147,20 @@ public class Status {
this.error = error;
}
+ public Double getCpuUsagePercent() {
+ if (cpuInfo == null) {
+ return 0.0;
+ }
+ return cpuInfo.getUsagePercent();
+ }
+
+ public Double getMemoryUsagePercent() {
+ if (memoryInfo == null) {
+ return 0.0;
+ }
+ return memoryInfo.getUsagePercent();
+ }
+
// 内部类定义
public static class CpuInfo {
private String modelName;
diff --git a/reisa-admin/reisaAdminSpring/src/main/resources/application-dev.properties b/reisa-admin/reisaAdminSpring/src/main/resources/application-dev.properties
new file mode 100644
index 0000000..ae86713
--- /dev/null
+++ b/reisa-admin/reisaAdminSpring/src/main/resources/application-dev.properties
@@ -0,0 +1,6 @@
+spring.application.name=reisaAdminSpring
+spring.data.mongodb.uri=mongodb://reisaAdmin:nbAC8hi8xdJeBDDT@127.0.0.1:27017/reisaadmin
+server.port=48102
+
+spring.data.redis.host=127.0.0.1
+spring.data.redis.port: 6379
\ No newline at end of file
diff --git a/reisa-admin/src/App.vue b/reisa-admin/src/App.vue
index 9f5f1df..7f9d738 100644
--- a/reisa-admin/src/App.vue
+++ b/reisa-admin/src/App.vue
@@ -497,13 +497,22 @@
v-model:value="selectedMonitorServers"
mode="multiple"
placeholder="请选择要监控的服务器"
- style="width: 800px; margin-right: 16px;"
+ style="width: 600px; margin-right: 16px;"
@change="loadMonitorData"
>
{{ server.name }} ({{ server.ipAddress }})
+
+
刷新数据
+
关闭监控
+
@@ -532,11 +550,11 @@