docker 的容器内部状态监控完成,测试已经完成
This commit is contained in:
parent
23ceadc163
commit
45c717924c
@ -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);
|
||||
}
|
||||
}
|
@ -39,7 +39,7 @@ public class RunNewContainer {
|
||||
/**
|
||||
* DNS
|
||||
*/
|
||||
private String dns;
|
||||
private List<String> dns;
|
||||
|
||||
/**
|
||||
* 容器别名
|
||||
@ -51,6 +51,13 @@ public class RunNewContainer {
|
||||
*/
|
||||
private String hostname;
|
||||
|
||||
/**
|
||||
* 网络名
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String networkMode;
|
||||
|
||||
|
||||
public List<String> findEnvList() {
|
||||
// 若 envGroup 为空,返回空列表;否则将 envGroup 转换为包含键值对字符串的列表
|
||||
|
@ -1,5 +1,9 @@
|
||||
package cd.casic.module.execute.docker.service;
|
||||
|
||||
import com.github.dockerjava.api.model.Statistics;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
/**
|
||||
* @description: TODO
|
||||
* @author: mianbin
|
||||
@ -8,4 +12,7 @@ package cd.casic.module.execute.docker.service;
|
||||
*/
|
||||
public interface IMonitorService {
|
||||
|
||||
Statistics monitorDocker(String clientId, String containerId);
|
||||
|
||||
BlockingQueue<Statistics> monitorsDocker(String clientId, String containerId);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -2,14 +2,15 @@ package cd.casic.module.execute;
|
||||
|
||||
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.RunNewContainer;
|
||||
import com.github.dockerjava.api.DockerClient;
|
||||
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.InspectContainerResponse;
|
||||
import com.github.dockerjava.api.command.TopContainerResponse;
|
||||
import com.github.dockerjava.api.exception.NotFoundException;
|
||||
import com.github.dockerjava.api.model.Container;
|
||||
import com.github.dockerjava.api.model.Frame;
|
||||
import com.github.dockerjava.api.model.*;
|
||||
import com.github.dockerjava.core.DockerClientBuilder;
|
||||
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -18,6 +19,7 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -79,12 +81,36 @@ public class ContainerServiceTest {
|
||||
System.out.println(exec.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* 能启动,但是参数都没生效的样子
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void start() {
|
||||
String containerId = "d7d747696f43";
|
||||
String imagesId = "be69f2940aaf";
|
||||
DockerClient dockerClient = clientGroup.get("158");
|
||||
dockerClient.startContainerCmd(containerId).exec();
|
||||
log.info("启动容器,containerId={}", containerId);
|
||||
// 创建 RunNewContainer 对象并设置属性
|
||||
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
|
||||
@ -190,4 +216,5 @@ public class ContainerServiceTest {
|
||||
.exec(new CommandExecCallback(containerId))
|
||||
.awaitCompletion();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import static java.lang.String.format;
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Slf4j
|
||||
public class DockerPingService {
|
||||
public class DockerPingServiceTest {
|
||||
private final Map<String, DockerClient> clientGroup = new ConcurrentHashMap<>();
|
||||
|
||||
private ApacheDockerHttpClient createHttpClient(DockerEndpoint endpoint) {
|
@ -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 {
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user