Commit 200e5658 authored by wutu's avatar wutu

添加了一个比较大的改动:使用两个定时线程进行Docker状态的实时检查

parent 048e08d6
......@@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import top.ninwoo.edgecenter.service.ClusterService;
import top.ninwoo.utils.entity.DockerContainer;
import java.util.List;
......@@ -14,8 +15,9 @@ public class IndexController {
ClusterService clusterService;
@RequestMapping("/index")
public List<String> index() {
List<String> containerIds = clusterService.getContainerIds();
public List<DockerContainer> index(int flag) {
List<DockerContainer> containerIds = clusterService.getContainerIds(flag == 0);
return containerIds;
}
}
package top.ninwoo.edgecenter.service;
import top.ninwoo.edgecenter.entity.ClusterConfig;
import top.ninwoo.utils.entity.DockerContainer;
import java.util.List;
import java.util.Set;
public interface ClusterService {
// 获取容器列表
List<String> getContainerIds();
List<DockerContainer> getContainerIds();
List<DockerContainer> getContainerIds(boolean isAll);
// 创建容器组
long initContainers(ClusterConfig clusterConfig);
// 获取集群列表
......
package top.ninwoo.edgecenter.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import top.ninwoo.edgecenter.entity.ClusterConfig;
import top.ninwoo.edgecenter.entity.ContainerDescription;
import top.ninwoo.edgecenter.scheduler.Scheduler;
import top.ninwoo.edgecenter.service.ClusterService;
import top.ninwoo.utils.entity.DockerContainer;
import top.ninwoo.utils.service.DockerService;
......@@ -19,7 +17,7 @@ import java.util.concurrent.ConcurrentHashMap;
* @description 集群服务类
*/
@Service
public class ClusterServiceImpl implements ClusterService, Scheduler {
public class ClusterServiceImpl implements ClusterService {
private ConcurrentHashMap<Long, Map<String, Set<String>>> clustersInfo = new ConcurrentHashMap<>();
@Autowired
DockerService dockerService;
......@@ -27,15 +25,29 @@ public class ClusterServiceImpl implements ClusterService, Scheduler {
/**
* 定时更新容器列表
*/
@Scheduled(fixedRate = 5000)
/*@Scheduled(fixedRate = 5000)
@Override
public void update() {
dockerService.updateContainers();
}*/
@Override
public List<DockerContainer> getContainerIds() {
return getContainerIds(false);
}
/**
* 返回容器的id
* @param isAll
* @return
*/
@Override
public List<String> getContainerIds() {
return dockerService.getDockerIds();
public List<DockerContainer> getContainerIds(boolean isAll) {
if(isAll) {
return dockerService.getAllContainers();
} else {
return dockerService.getRunningContainers();
}
}
/**
......
package top.ninwoo.utils.service;
/**
* @Author joliu
* @Description
* @Date Create in 下午3:35 2019/10/25
*/
public enum ContainerStatus {
RUNNING("Running"),STOPPED("Stopped");
private String status;
ContainerStatus(String status) {
this.status = status;
}
}
package top.ninwoo.utils.service;
import org.springframework.scheduling.annotation.Scheduled;
import top.ninwoo.utils.entity.DockerContainer;
import java.util.List;
import java.util.Map;
import java.util.Set;
public interface DockerService {
List<String> getDockerIds();
List<String> getDockerIds(boolean isAll);
void updateContainers();
void updateContainers(boolean flag);
/**
* 启动一个Docker容器
* @param container
* @return
*/
DockerContainer runDocker(DockerContainer container);
void getContainers();
/**
* 获取容器状态
* @param containerId
* @return
*/
ContainerStatus getContainerStatus(String containerId);
Map<String, DockerContainer> getContainers(boolean isfull);
List<DockerContainer> getAllContainers();
DockerContainer runDocker(DockerContainer container);
DockerContainer getDockerById(String id);
/**
* 获取存活的Docker列表
* @return
*/
List<DockerContainer> getRunningContainers();
/**
* 获取容器数量
* @param isAll 是否包含停止的容器
* @return
*/
int getContainersNumber(boolean isAll);
/**
* 通过容器id关闭容器
* @param id
* @return
*/
boolean deleteDockerById(String id);
/**
* 批量关闭docker容器
* @param ids
* @return
*/
boolean deleteDockerByIds(List<String> ids);
/**
* 更新Docker容器列表
* 这是一个定时任务
*/
void addNewContainers();
/**
* 检查map中docker的运行状态
* 这是一个定时任务
*/
void delExitedContainers();
/**
* 检查docker容器状态
* @param containerId
* @return
*/
ContainerStatus checkContainerStatus(String containerId);
/**
* 通过docker容器id获取容器详情
* TODO: DockerContainer需要补充一个容器状态
* @param id
* @return
*/
DockerContainer getDockerById(String id);
/**
* 初始化当前的容器信息
*/
void init();
}
......@@ -2,44 +2,32 @@ package top.ninwoo.utils.service.impl;
import com.spotify.docker.client.messages.Container;
import com.spotify.docker.client.messages.ContainerInfo;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import top.ninwoo.utils.entity.DockerContainer;
import top.ninwoo.utils.service.ContainerStatus;
import top.ninwoo.utils.service.DockerService;
import top.ninwoo.utils.util.DockerUtils;
import top.ninwoo.utils.util.LinuxCtlUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
@Service
public class DockerServiceImpl implements DockerService {
@Autowired
private LinuxCtlUtils linuxCtlUtils;
public class DockerServiceImpl implements DockerService, InitializingBean {
@Autowired
private DockerUtils dockerUtils;
// 这里考虑要不要区分正在运行中的容器
private ConcurrentHashMap<String, DockerContainer> containersMap = new ConcurrentHashMap<>();
// 运行中的Docker
private ConcurrentHashMap<String, DockerContainer> runingContainers = new ConcurrentHashMap<>();
// 停止的Docker
private ConcurrentHashMap<String, DockerContainer> allContainers = new ConcurrentHashMap<>();
@Override
public List<String> getDockerIds() {
return getDockerIds(false);
}
/**
* 获取容器Id
* @param isAll 是否获取全部的容器id,包含未启动的容器
* @return
*/
@Override
public List<String> getDockerIds(boolean isAll) {
return new ArrayList<String>(containersMap.keySet());
}
private ReentrantLock lock = new ReentrantLock();
/**
* 将DockerClient获取的到结果封装成为我们自定义的数据结构
......@@ -65,29 +53,6 @@ public class DockerServiceImpl implements DockerService {
return dockerContainers;
}
@Override
public void getContainers() {
updateContainers(true);
}
/**
* @description 更新容器列表
* @param isfull true:全量更新
* @date 2019-10-20
* 修改该服务类为完全无状态的类,容器信息由上层集群服务维护 修改了
* @see DockerServiceImpl#updateContainers(boolean)
* @see DockerServiceImpl#updateContainers()
* @return
*/
@Override
public Map<String, DockerContainer> getContainers(boolean isfull) {
if(containersMap.isEmpty()) {
return dockerUtils.getContainers();
} else {
// TODO: 先执行增量更新,在返回结果
return dockerUtils.getContainers();
}
}
/**
* 使用系统命令 docker run -itd 在后台启动一个容器,
......@@ -125,21 +90,84 @@ public class DockerServiceImpl implements DockerService {
}
@Override
public void updateContainers() {
updateContainers(true);
public ContainerStatus getContainerStatus(String containerId) {
// 这里查找docker容器状态可能和全量更新产生问题
return ContainerStatus.RUNNING;
}
@Override
public void updateContainers(boolean isfull) {
if(isfull) {
// 清空
containersMap.clear();
List<Container> containers =
new ArrayList<Container>();
containersMap.putAll(dockerUtils.getContainers());
} else {
// TODO: 增量备份
}
public List<DockerContainer> getRunningContainers() {
return new ArrayList<>(runingContainers.values());
}
@Override
public int getContainersNumber(boolean isAll) {
return isAll ? allContainers.size() : runingContainers.size();
}
@Override
public boolean deleteDockerByIds(List<String> ids) {
return false;
}
@Override
public void init() {
runingContainers.clear();
allContainers.clear();
List<Container> containers =
new ArrayList<Container>();
runingContainers.putAll(dockerUtils.getContainers(false));
allContainers.putAll(dockerUtils.getContainers(true));
}
@Scheduled(fixedRate = 500)
@Override
public void addNewContainers() {
Map<String, DockerContainer> containers = dockerUtils.getContainers(false);
containers.forEach((cid, container) -> {
if(runingContainers.containsKey(cid)) {
// do nothing
} else {
// 添加到map中
runingContainers.put(cid, container);
// 更新allContainers
allContainers.put(cid, container);
}
});
}
/**
* 删除Running Map中停止的容器
*/
@Scheduled(fixedRate = 500)
@Override
public void delExitedContainers() {
runingContainers.keySet().forEach(cid -> {
DockerContainer dockerById = dockerUtils.getDockerById(cid);
if(dockerById == null) {
// 容器已经被删除
runingContainers.remove(cid);
allContainers.remove(cid);
} else if(dockerById.getStatus().contains("exited")) {
runingContainers.remove(cid);
}
});
}
@Override
public ContainerStatus checkContainerStatus(String containerId) {
return null;
}
@Override
public List<DockerContainer> getAllContainers() {
return new ArrayList<DockerContainer>(allContainers.values());
}
@Override
public void afterPropertiesSet() throws Exception {
init();
}
}
package top.ninwoo.utils.util.impl;
import com.spotify.docker.client.DockerClient;
import com.spotify.docker.client.exceptions.ContainerNotFoundException;
import com.spotify.docker.client.exceptions.DockerException;
import com.spotify.docker.client.messages.Container;
import com.spotify.docker.client.messages.ContainerInfo;
......@@ -45,7 +46,7 @@ public class DockerUtilsImpl implements DockerUtils {
containers = dockerClient.listContainers(DockerClient.ListContainersParam.withStatusRunning());
} else {
// TODO:这里边还需要在确定
containers = dockerClient.listContainers(DockerClient.ListContainersParam.withStatusCreated());
containers = dockerClient.listContainers(DockerClient.ListContainersParam.allContainers());
}
} catch (DockerException e) {
e.printStackTrace();
......@@ -106,6 +107,8 @@ public class DockerUtilsImpl implements DockerUtils {
ContainerInfo containerInfo = null;
try {
containerInfo = dockerClient.inspectContainer(id);
} catch (ContainerNotFoundException e) {
return null;
} catch (DockerException e) {
e.printStackTrace();
} catch (InterruptedException e) {
......
......@@ -41,12 +41,14 @@ public class DockerServiceTests {
System.out.println(result);
}
@Test
/*@Test
public void testUpdateDockerService() {
dockerService.updateContainers();
List<String> dockerIds = dockerService.getDockerIds();
dockerIds.forEach(d-> System.out.println(d));
}
dockerService.updateContainersList(true);
List<DockerContainer> allContainers = dockerService.getAllContainers();
allContainers.forEach(c -> {
System.out.println(c.getId() + ":" + c.getStatus());
});
}*/
@Test
public void testRunDockerService() {
......
package top.ninwoo.utils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Assert;
import top.ninwoo.utils.config.DockerConfig;
import top.ninwoo.utils.entity.DockerContainer;
import top.ninwoo.utils.util.DockerUtils;
/**
* @Author joliu
* @Description
* @Date Create in 下午5:54 2019/10/25
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = DockerConfig.class)
public class DockerUtilsTest {
@Autowired
DockerUtils dockerUtils;
@Test
public void testGetDockerById() {
DockerContainer dockerById = dockerUtils.getDockerById("123123");
Assert.isNull(dockerById);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment