docker 的容器内部状态监控完成,测试已经完成

This commit is contained in:
mianbin 2025-05-28 11:55:36 +08:00
parent 23ceadc163
commit 45c717924c
7 changed files with 197 additions and 18 deletions

View File

@ -0,0 +1,49 @@
package cd.casic.module.execute.docker.callback;
import com.github.dockerjava.api.async.ResultCallback;
import com.github.dockerjava.api.model.Statistics;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
/**
* @description: 镜像的状态监控
* @author: mianbin
* @date: 2025/5/28 10:45
* @version: 1.0
*/
@Data
@Slf4j
public class MonitorCallback extends ResultCallback.Adapter<Statistics> {
private Statistics statistics;
private CompletableFuture<Statistics> future = new CompletableFuture<>();
@Override
public void onNext(Statistics statistics) {
future.complete(statistics);
super.onNext(statistics);
log.info("状态使用情况:{}", statistics);
}
@Override
public void onError(Throwable throwable) {
super.onError(throwable);
log.error("docker 拉取异常,{}", throwable.getMessage());
future.completeExceptionally(throwable);
}
@Override
public void onComplete() {
super.onComplete();
log.info("完成:{}", 1);
}
@Override
public void close() throws IOException {
super.close();
log.info("关闭:{}", 1);
}
}

View File

@ -39,7 +39,7 @@ public class RunNewContainer {
/** /**
* DNS * DNS
*/ */
private String dns; private List<String> dns;
/** /**
* 容器别名 * 容器别名
@ -51,6 +51,13 @@ public class RunNewContainer {
*/ */
private String hostname; private String hostname;
/**
* 网络名
*
* @return
*/
private String networkMode;
public List<String> findEnvList() { public List<String> findEnvList() {
// envGroup 为空返回空列表否则将 envGroup 转换为包含键值对字符串的列表 // envGroup 为空返回空列表否则将 envGroup 转换为包含键值对字符串的列表

View File

@ -1,5 +1,9 @@
package cd.casic.module.execute.docker.service; package cd.casic.module.execute.docker.service;
import com.github.dockerjava.api.model.Statistics;
import java.util.concurrent.BlockingQueue;
/** /**
* @description: TODO * @description: TODO
* @author: mianbin * @author: mianbin
@ -8,4 +12,7 @@ package cd.casic.module.execute.docker.service;
*/ */
public interface IMonitorService { public interface IMonitorService {
Statistics monitorDocker(String clientId, String containerId);
BlockingQueue<Statistics> monitorsDocker(String clientId, String containerId);
} }

View File

@ -0,0 +1,100 @@
package cd.casic.module.execute.docker.service.impl;
import cd.casic.module.execute.docker.DockerClientFactory;
import cd.casic.module.execute.docker.service.IMonitorService;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.async.ResultCallback;
import com.github.dockerjava.api.model.Statistics;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.concurrent.*;
/**
* @description:
* @author: mianbin
* @date: 2025/5/28 11:07
* @version: 1.0
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class MonitorService implements IMonitorService {
private final DockerClientFactory dockerClientFactory;
/*
* 镜像里面的监控获取没问题但是如果你是获取持续的比如一直获取那么这个就不行这个是一次的
* */
@Override
public Statistics monitorDocker(String clientId, String containerId) {
CompletableFuture<Statistics> future = new CompletableFuture<>();
DockerClient dockerClient = dockerClientFactory.getdockerClient(clientId);
dockerClient.statsCmd(containerId).exec(new ResultCallback.Adapter<Statistics>() {
@SneakyThrows(RuntimeException.class)
@Override
public void onNext(Statistics statistics) {
future.complete(statistics);
// throw new RuntimeException("镜像{" + containerId + "},采集状态失败,停止运行");
}
@Override
public void onError(Throwable throwable) {
if (throwable instanceof RuntimeException) {
return;
}
log.error("docker 拉取状态异常,{}", throwable.getMessage());
future.completeExceptionally(throwable);
}
});
try {
// 最多等待 3
Statistics statistics = future.get(3, TimeUnit.SECONDS);
return statistics;
} catch (TimeoutException e) {
log.warn("获取 Docker 统计信息超时");
return new Statistics();
} catch (InterruptedException | ExecutionException e) {
log.error("获取 Docker 统计信息出错", e);
return new Statistics();
}
}
@Override
public BlockingQueue<Statistics> monitorsDocker(String clientId, String containerId) {
// 创建一个阻塞队列用于存储持续获取的统计信息
BlockingQueue<Statistics> statsQueue = new LinkedBlockingQueue<>();
DockerClient dockerClient = dockerClientFactory.getdockerClient(clientId);
dockerClient.statsCmd(containerId).exec(new ResultCallback.Adapter<Statistics>() {
@Override
public void onNext(Statistics statistics) {
try {
// 将获取到的统计信息添加到队列中
statsQueue.put(statistics);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("向队列添加统计信息时被中断", e);
}
}
@Override
public void onError(Throwable throwable) {
log.error("docker 拉取状态异常,{}", throwable.getMessage());
}
@Override
public void onComplete() {
log.info("Docker 状态监控完成");
try {
super.close();
} catch (IOException e) {
// igonre it
}
}
});
return statsQueue;
}
}

View File

@ -2,14 +2,15 @@ package cd.casic.module.execute;
import cd.casic.module.execute.docker.callback.CommandExecCallback; import cd.casic.module.execute.docker.callback.CommandExecCallback;
import cd.casic.module.execute.docker.dataobject.model.DockerEndpoint; import cd.casic.module.execute.docker.dataobject.model.DockerEndpoint;
import cd.casic.module.execute.docker.dataobject.model.RunNewContainer;
import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.async.ResultCallback; import com.github.dockerjava.api.async.ResultCallback;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.command.ExecCreateCmdResponse; import com.github.dockerjava.api.command.ExecCreateCmdResponse;
import com.github.dockerjava.api.command.InspectContainerResponse; import com.github.dockerjava.api.command.InspectContainerResponse;
import com.github.dockerjava.api.command.TopContainerResponse; import com.github.dockerjava.api.command.TopContainerResponse;
import com.github.dockerjava.api.exception.NotFoundException; import com.github.dockerjava.api.exception.NotFoundException;
import com.github.dockerjava.api.model.Container; import com.github.dockerjava.api.model.*;
import com.github.dockerjava.api.model.Frame;
import com.github.dockerjava.core.DockerClientBuilder; import com.github.dockerjava.core.DockerClientBuilder;
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient; import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -18,6 +19,7 @@ import org.junit.jupiter.api.Test;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -79,12 +81,36 @@ public class ContainerServiceTest {
System.out.println(exec.size()); System.out.println(exec.size());
} }
/**
* 能启动但是参数都没生效的样子
*
*/
@Test @Test
public void start() { public void start() {
String containerId = "d7d747696f43"; String imagesId = "be69f2940aaf";
DockerClient dockerClient = clientGroup.get("158"); DockerClient dockerClient = clientGroup.get("158");
dockerClient.startContainerCmd(containerId).exec(); // 创建 RunNewContainer 对象并设置属性
log.info("启动容器,containerId={}", containerId); RunNewContainer runNewContainer = new RunNewContainer();
runNewContainer.setImageId(imagesId);
runNewContainer.setAlias("nginx");
runNewContainer.setDns(Arrays.asList("8.8.8.8", "8.8.4.4"));
runNewContainer.setContainerName("nginx_test_api");
runNewContainer.setHostname("nginx.testapi.host.name");
Map<String, String> key1 = Map.of("KEY1", "VALUE1", "KEY2", "VALUE2");
runNewContainer.setEnvGroup(key1);
runNewContainer.setNetworkMode("nginx_test_net_work");
HostConfig hostConfig = HostConfig.newHostConfig();
hostConfig.withBinds(Bind.parse("/host:/container:ro"))
.withPortBindings(PortBinding.parse("12:44"))
.withDns(runNewContainer.getDns()).withNetworkMode(runNewContainer.getNetworkMode());
final CreateContainerResponse response = dockerClient
.createContainerCmd(runNewContainer.getImageId())
.withAliases(runNewContainer.getAlias())
.withHostConfig(hostConfig)
.withEnv(runNewContainer.findEnvList())
.withName(runNewContainer.getContainerName())
.withHostName(runNewContainer.getHostname()).exec();
} }
@Test @Test
@ -190,4 +216,5 @@ public class ContainerServiceTest {
.exec(new CommandExecCallback(containerId)) .exec(new CommandExecCallback(containerId))
.awaitCompletion(); .awaitCompletion();
} }
} }

View File

@ -25,7 +25,7 @@ import static java.lang.String.format;
* @version: 1.0 * @version: 1.0
*/ */
@Slf4j @Slf4j
public class DockerPingService { public class DockerPingServiceTest {
private final Map<String, DockerClient> clientGroup = new ConcurrentHashMap<>(); private final Map<String, DockerClient> clientGroup = new ConcurrentHashMap<>();
private ApacheDockerHttpClient createHttpClient(DockerEndpoint endpoint) { private ApacheDockerHttpClient createHttpClient(DockerEndpoint endpoint) {

View File

@ -1,11 +0,0 @@
package cd.casic.module.execute;
/**
* @description: TODO
* @author: mianbin
* @date: 2025/5/26 20:11
* @version: 1.0
*/
public class MonitorService {
}