From 3cc371c53e265800eb1164e3da5d378bce2f1d5e Mon Sep 17 00:00:00 2001 From: Timi Date: Mon, 13 Apr 2026 18:27:29 +0800 Subject: [PATCH] v1.0.2 --- .../modules/system/task/DockerStatusTask.java | 78 ++++++++++++++----- .../modules/system/task/UpsStatusTask.java | 2 +- .../system/util/DockerEngineClient.java | 23 ++++++ src/main/resources/application.yml | 4 + 4 files changed, 88 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/imyeyu/api/modules/system/task/DockerStatusTask.java b/src/main/java/com/imyeyu/api/modules/system/task/DockerStatusTask.java index 24827bb..71d8550 100644 --- a/src/main/java/com/imyeyu/api/modules/system/task/DockerStatusTask.java +++ b/src/main/java/com/imyeyu/api/modules/system/task/DockerStatusTask.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.imyeyu.api.modules.system.bean.DockerStatusStore; import com.imyeyu.api.modules.system.util.DockerEngineClient; +import com.imyeyu.java.TimiJava; import com.imyeyu.utils.Time; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; @@ -15,12 +16,13 @@ import org.springframework.scheduling.support.PeriodicTrigger; import org.springframework.stereotype.Service; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; /** - * Docker 鐘舵€侀噰闆嗕换鍔? + * Docker 容器状态采集任务 * * @author Codex * @since 2026-04-06 @@ -56,19 +58,27 @@ public class DockerStatusTask implements SchedulingConfigurer { try { ArrayNode containers = (ArrayNode) dockerEngineClient.getJson("/containers/json", DockerEngineClient.query("all", "true")); long now = Time.now(); - synchronized (dockerStatusStore) { - Set activeIds = new HashSet<>(); - for (JsonNode summary : containers) { - try { - String containerId = getAsString(summary, "Id"); - activeIds.add(containerId); - DockerStatusStore.Container container = dockerStatusStore.getContainers().computeIfAbsent(containerId, key -> new DockerStatusStore.Container()); - updateContainerSummary(container, summary); - updateContainerInspect(containerId, container); - updateContainerStats(containerId, container, now); - } catch (Exception e) { - log.error("collect docker container item error", e); + Map collectedContainers = new LinkedHashMap<>(); + for (JsonNode summary : containers) { + try { + String containerId = getAsString(summary, "Id"); + DockerStatusStore.Container container = new DockerStatusStore.Container(); + if (TimiJava.isEmpty(container)) { + continue; } + updateContainerSummary(container, summary); + updateContainerInspect(containerId, container); + updateContainerStats(containerId, container, now); + collectedContainers.put(container.getId(), container); + } catch (Exception e) { + log.error("collect docker container item error", e); + } + } + synchronized (dockerStatusStore) { + Set activeIds = new HashSet<>(collectedContainers.keySet()); + for (Map.Entry item : collectedContainers.entrySet()) { + DockerStatusStore.Container container = dockerStatusStore.getContainers().computeIfAbsent(item.getKey(), key -> new DockerStatusStore.Container()); + applyCollectedContainer(container, item.getValue()); } dockerStatusStore.getContainers().entrySet().removeIf(item -> !activeIds.contains(item.getKey())); } @@ -77,6 +87,39 @@ public class DockerStatusTask implements SchedulingConfigurer { } } + private void applyCollectedContainer(DockerStatusStore.Container target, DockerStatusStore.Container source) { + target.setId(source.getId()); + target.setName(source.getName()); + target.setImage(source.getImage()); + target.setImageId(source.getImageId()); + target.setCreatedAt(source.getCreatedAt()); + target.setState(source.getState()); + target.setStatus(source.getStatus()); + target.setHealthStatus(source.getHealthStatus()); + target.setStartedAt(source.getStartedAt()); + target.setFinishedAt(source.getFinishedAt()); + target.setExitCode(source.getExitCode()); + target.setRestartCount(source.getRestartCount()); + target.setOomKilled(source.isOomKilled()); + target.setCpuPercent(source.getCpuPercent()); + target.setMemoryUsageBytes(source.getMemoryUsageBytes()); + target.setMemoryLimitBytes(source.getMemoryLimitBytes()); + target.setMemoryPercent(source.getMemoryPercent()); + target.setNetworkRxBytes(source.getNetworkRxBytes()); + target.setNetworkTxBytes(source.getNetworkTxBytes()); + target.setBlockReadBytes(source.getBlockReadBytes()); + target.setBlockWriteBytes(source.getBlockWriteBytes()); + target.setPids(source.getPids()); + target.setUpdatedAt(source.getUpdatedAt()); + DockerStatusStore.Point point = source.getHistory().peekLast(); + if (point != null) { + target.getHistory().addLast(point); + while (historyLimit < target.getHistory().size()) { + target.getHistory().pollFirst(); + } + } + } + private void updateContainerSummary(DockerStatusStore.Container container, JsonNode summary) { container.setId(getAsString(summary, "Id")); container.setName(trimContainerName(readFirstArrayText(summary, "Names"))); @@ -108,8 +151,8 @@ public class DockerStatusTask implements SchedulingConfigurer { if (memoryUsageBytes != null && memoryLimitBytes != null && 0 < memoryLimitBytes) { memoryPercent = memoryUsageBytes * 100D / memoryLimitBytes; } - Long networkRxBytes = 0L; - Long networkTxBytes = 0L; + long networkRxBytes = 0L; + long networkTxBytes = 0L; JsonNode networks = getAsObject(stats, "networks"); if (networks != null) { for (Map.Entry item : (Iterable>) networks::fields) { @@ -118,8 +161,8 @@ public class DockerStatusTask implements SchedulingConfigurer { networkTxBytes += getAsLong(network, "tx_bytes", 0L); } } - Long blockReadBytes = 0L; - Long blockWriteBytes = 0L; + long blockReadBytes = 0L; + long blockWriteBytes = 0L; JsonNode blkioStats = getAsObject(stats, "blkio_stats"); ArrayNode ioServiceBytes = blkioStats == null ? null : getAsArray(blkioStats, "io_service_bytes_recursive"); if (ioServiceBytes != null) { @@ -134,7 +177,6 @@ public class DockerStatusTask implements SchedulingConfigurer { } } Integer pids = getNestedInteger(stats, "pids_stats", "current"); - container.setCpuPercent(cpuPercent); container.setMemoryUsageBytes(memoryUsageBytes); container.setMemoryLimitBytes(memoryLimitBytes); diff --git a/src/main/java/com/imyeyu/api/modules/system/task/UpsStatusTask.java b/src/main/java/com/imyeyu/api/modules/system/task/UpsStatusTask.java index 1064bc9..f84eca1 100644 --- a/src/main/java/com/imyeyu/api/modules/system/task/UpsStatusTask.java +++ b/src/main/java/com/imyeyu/api/modules/system/task/UpsStatusTask.java @@ -28,7 +28,7 @@ public class UpsStatusTask implements SchedulingConfigurer { private final UpsStatusClient upsStatusClient; private final UpsStatusStore upsStatusStore; - @Value("${ups.collect-enabled:true}") + @Value("${ups.collect-enabled:false}") private boolean collectEnabled; @Value("${ups.collect-rate-ms:60000}") diff --git a/src/main/java/com/imyeyu/api/modules/system/util/DockerEngineClient.java b/src/main/java/com/imyeyu/api/modules/system/util/DockerEngineClient.java index abe64fd..291b578 100644 --- a/src/main/java/com/imyeyu/api/modules/system/util/DockerEngineClient.java +++ b/src/main/java/com/imyeyu/api/modules/system/util/DockerEngineClient.java @@ -18,6 +18,7 @@ import java.net.http.HttpResponse; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; import java.time.Duration; import java.util.LinkedHashMap; @@ -73,6 +74,28 @@ public class DockerEngineClient { } } + /** + * 判断 Docker Engine 当前是否可访问。 + * + * @return 可访问返回 true,不可访问返回 false + */ + public boolean isAvailable() { + if (host.startsWith("unix://")) { + String socketPath = host.substring("unix://".length()); + return Files.exists(Path.of(socketPath)); + } + return true; + } + + /** + * 获取 Docker Engine 主机配置。 + * + * @return 主机配置字符串 + */ + public String getHost() { + return host; + } + private String buildRequestPath(String path, Map queryParams) { StringBuilder builder = new StringBuilder(); builder.append("/"); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 37224d4..e3d801e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,5 +1,9 @@ server: shutdown: graceful + # 压缩 + compression: + enable: true + min-response-size: 10KB # 开发环境语言,激活开发配置时,多语言系统始终使用此语言环境 dev: