Commit 200e5658 authored by wutu's avatar wutu

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

parent 048e08d6
...@@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import top.ninwoo.edgecenter.service.ClusterService; import top.ninwoo.edgecenter.service.ClusterService;
import top.ninwoo.utils.entity.DockerContainer;
import java.util.List; import java.util.List;
...@@ -14,8 +15,9 @@ public class IndexController { ...@@ -14,8 +15,9 @@ public class IndexController {
ClusterService clusterService; ClusterService clusterService;
@RequestMapping("/index") @RequestMapping("/index")
public List<String> index() { public List<DockerContainer> index(int flag) {
List<String> containerIds = clusterService.getContainerIds();
List<DockerContainer> containerIds = clusterService.getContainerIds(flag == 0);
return containerIds; return containerIds;
} }
} }
package top.ninwoo.edgecenter.service; package top.ninwoo.edgecenter.service;
import top.ninwoo.edgecenter.entity.ClusterConfig; import top.ninwoo.edgecenter.entity.ClusterConfig;
import top.ninwoo.utils.entity.DockerContainer;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
public interface ClusterService { public interface ClusterService {
// 获取容器列表 // 获取容器列表
List<String> getContainerIds(); List<DockerContainer> getContainerIds();
List<DockerContainer> getContainerIds(boolean isAll);
// 创建容器组 // 创建容器组
long initContainers(ClusterConfig clusterConfig); long initContainers(ClusterConfig clusterConfig);
// 获取集群列表 // 获取集群列表
......
package top.ninwoo.edgecenter.service.impl; package top.ninwoo.edgecenter.service.impl;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import top.ninwoo.edgecenter.entity.ClusterConfig; import top.ninwoo.edgecenter.entity.ClusterConfig;
import top.ninwoo.edgecenter.entity.ContainerDescription; import top.ninwoo.edgecenter.entity.ContainerDescription;
import top.ninwoo.edgecenter.scheduler.Scheduler;
import top.ninwoo.edgecenter.service.ClusterService; import top.ninwoo.edgecenter.service.ClusterService;
import top.ninwoo.utils.entity.DockerContainer; import top.ninwoo.utils.entity.DockerContainer;
import top.ninwoo.utils.service.DockerService; import top.ninwoo.utils.service.DockerService;
...@@ -19,7 +17,7 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -19,7 +17,7 @@ import java.util.concurrent.ConcurrentHashMap;
* @description 集群服务类 * @description 集群服务类
*/ */
@Service @Service
public class ClusterServiceImpl implements ClusterService, Scheduler { public class ClusterServiceImpl implements ClusterService {
private ConcurrentHashMap<Long, Map<String, Set<String>>> clustersInfo = new ConcurrentHashMap<>(); private ConcurrentHashMap<Long, Map<String, Set<String>>> clustersInfo = new ConcurrentHashMap<>();
@Autowired @Autowired
DockerService dockerService; DockerService dockerService;
...@@ -27,15 +25,29 @@ public class ClusterServiceImpl implements ClusterService, Scheduler { ...@@ -27,15 +25,29 @@ public class ClusterServiceImpl implements ClusterService, Scheduler {
/** /**
* 定时更新容器列表 * 定时更新容器列表
*/ */
@Scheduled(fixedRate = 5000) /*@Scheduled(fixedRate = 5000)
@Override @Override
public void update() { public void update() {
dockerService.updateContainers(); dockerService.updateContainers();
}*/
@Override
public List<DockerContainer> getContainerIds() {
return getContainerIds(false);
} }
/**
* 返回容器的id
* @param isAll
* @return
*/
@Override @Override
public List<String> getContainerIds() { public List<DockerContainer> getContainerIds(boolean isAll) {
return dockerService.getDockerIds(); 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; package top.ninwoo.utils.service;
import org.springframework.scheduling.annotation.Scheduled;
import top.ninwoo.utils.entity.DockerContainer; import top.ninwoo.utils.entity.DockerContainer;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
public interface DockerService { public interface DockerService {
List<String> getDockerIds(); /**
List<String> getDockerIds(boolean isAll); * 启动一个Docker容器
void updateContainers(); * @param container
void updateContainers(boolean flag); * @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); 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; ...@@ -2,44 +2,32 @@ package top.ninwoo.utils.service.impl;
import com.spotify.docker.client.messages.Container; import com.spotify.docker.client.messages.Container;
import com.spotify.docker.client.messages.ContainerInfo; import com.spotify.docker.client.messages.ContainerInfo;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import top.ninwoo.utils.entity.DockerContainer; import top.ninwoo.utils.entity.DockerContainer;
import top.ninwoo.utils.service.ContainerStatus;
import top.ninwoo.utils.service.DockerService; import top.ninwoo.utils.service.DockerService;
import top.ninwoo.utils.util.DockerUtils; import top.ninwoo.utils.util.DockerUtils;
import top.ninwoo.utils.util.LinuxCtlUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
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;
import java.util.concurrent.locks.ReentrantLock;
@Service @Service
public class DockerServiceImpl implements DockerService { public class DockerServiceImpl implements DockerService, InitializingBean {
@Autowired
private LinuxCtlUtils linuxCtlUtils;
@Autowired @Autowired
private DockerUtils dockerUtils; private DockerUtils dockerUtils;
// 这里考虑要不要区分正在运行中的容器 // 运行中的Docker
private ConcurrentHashMap<String, DockerContainer> containersMap = new ConcurrentHashMap<>(); private ConcurrentHashMap<String, DockerContainer> runingContainers = new ConcurrentHashMap<>();
// 停止的Docker
private ConcurrentHashMap<String, DockerContainer> allContainers = new ConcurrentHashMap<>();
@Override private ReentrantLock lock = new ReentrantLock();
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());
}
/** /**
* 将DockerClient获取的到结果封装成为我们自定义的数据结构 * 将DockerClient获取的到结果封装成为我们自定义的数据结构
...@@ -65,29 +53,6 @@ public class DockerServiceImpl implements DockerService { ...@@ -65,29 +53,6 @@ public class DockerServiceImpl implements DockerService {
return dockerContainers; 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 在后台启动一个容器, * 使用系统命令 docker run -itd 在后台启动一个容器,
...@@ -125,21 +90,84 @@ public class DockerServiceImpl implements DockerService { ...@@ -125,21 +90,84 @@ public class DockerServiceImpl implements DockerService {
} }
@Override @Override
public void updateContainers() { public ContainerStatus getContainerStatus(String containerId) {
updateContainers(true); // 这里查找docker容器状态可能和全量更新产生问题
return ContainerStatus.RUNNING;
} }
@Override @Override
public void updateContainers(boolean isfull) { public List<DockerContainer> getRunningContainers() {
if(isfull) { return new ArrayList<>(runingContainers.values());
// 清空 }
containersMap.clear();
List<Container> containers = @Override
new ArrayList<Container>(); public int getContainersNumber(boolean isAll) {
return isAll ? allContainers.size() : runingContainers.size();
containersMap.putAll(dockerUtils.getContainers()); }
} else {
// TODO: 增量备份 @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; package top.ninwoo.utils.util.impl;
import com.spotify.docker.client.DockerClient; 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.exceptions.DockerException;
import com.spotify.docker.client.messages.Container; import com.spotify.docker.client.messages.Container;
import com.spotify.docker.client.messages.ContainerInfo; import com.spotify.docker.client.messages.ContainerInfo;
...@@ -45,7 +46,7 @@ public class DockerUtilsImpl implements DockerUtils { ...@@ -45,7 +46,7 @@ public class DockerUtilsImpl implements DockerUtils {
containers = dockerClient.listContainers(DockerClient.ListContainersParam.withStatusRunning()); containers = dockerClient.listContainers(DockerClient.ListContainersParam.withStatusRunning());
} else { } else {
// TODO:这里边还需要在确定 // TODO:这里边还需要在确定
containers = dockerClient.listContainers(DockerClient.ListContainersParam.withStatusCreated()); containers = dockerClient.listContainers(DockerClient.ListContainersParam.allContainers());
} }
} catch (DockerException e) { } catch (DockerException e) {
e.printStackTrace(); e.printStackTrace();
...@@ -106,6 +107,8 @@ public class DockerUtilsImpl implements DockerUtils { ...@@ -106,6 +107,8 @@ public class DockerUtilsImpl implements DockerUtils {
ContainerInfo containerInfo = null; ContainerInfo containerInfo = null;
try { try {
containerInfo = dockerClient.inspectContainer(id); containerInfo = dockerClient.inspectContainer(id);
} catch (ContainerNotFoundException e) {
return null;
} catch (DockerException e) { } catch (DockerException e) {
e.printStackTrace(); e.printStackTrace();
} catch (InterruptedException e) { } catch (InterruptedException e) {
......
...@@ -41,12 +41,14 @@ public class DockerServiceTests { ...@@ -41,12 +41,14 @@ public class DockerServiceTests {
System.out.println(result); System.out.println(result);
} }
@Test /*@Test
public void testUpdateDockerService() { public void testUpdateDockerService() {
dockerService.updateContainers(); dockerService.updateContainersList(true);
List<String> dockerIds = dockerService.getDockerIds(); List<DockerContainer> allContainers = dockerService.getAllContainers();
dockerIds.forEach(d-> System.out.println(d)); allContainers.forEach(c -> {
} System.out.println(c.getId() + ":" + c.getStatus());
});
}*/
@Test @Test
public void testRunDockerService() { 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