Commit 40e34aff authored by wutu's avatar wutu

新添加了几个linux服务器信息的接口,发现了限速模块的速率bug

parent 254c58e1
...@@ -7,6 +7,10 @@ import top.ninwoo.utils.entity.OvsBridge; ...@@ -7,6 +7,10 @@ import top.ninwoo.utils.entity.OvsBridge;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
/**
* 这个模块的
* @author joliu
*/
public interface ClusterService { public interface ClusterService {
// 获取容器列表 // 获取容器列表
List<DockerContainer> getContainerIds(); List<DockerContainer> getContainerIds();
...@@ -19,9 +23,11 @@ public interface ClusterService { ...@@ -19,9 +23,11 @@ public interface ClusterService {
Set<Long> getClusterIds(); Set<Long> getClusterIds();
// 通过集群Id获取集群中包含的容器IDs // 通过集群Id获取集群中包含的容器IDs
Set<String> getContainerIdsByClusterId(long clusterId, String containerName); Set<String> getContainerIdsByClusterId(long clusterId, String containerName);
// 移除Docker集群
void removeContainersByClusterId(long clusterId); void removeContainersByClusterId(long clusterId);
// 移除Docker集群中的某个容器
void removeContainersByClusterIdAndContainerName(long clusterId, String name); void removeContainersByClusterIdAndContainerName(long clusterId, String name);
// 获取网桥信息
List<OvsBridge> getOvsBridges(); List<OvsBridge> getOvsBridges();
} }
...@@ -16,6 +16,7 @@ import top.ninwoo.utils.entity.DockerContainer; ...@@ -16,6 +16,7 @@ import top.ninwoo.utils.entity.DockerContainer;
import top.ninwoo.utils.service.DockerService; import top.ninwoo.utils.service.DockerService;
import top.ninwoo.utils.service.OVSService; import top.ninwoo.utils.service.OVSService;
import top.ninwoo.utils.service.OvsDockerService; import top.ninwoo.utils.service.OvsDockerService;
import top.ninwoo.utils.service.TcService;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
...@@ -41,6 +42,9 @@ public class InDockerTests { ...@@ -41,6 +42,9 @@ public class InDockerTests {
@Autowired @Autowired
OvsDockerService ovsDockerService; OvsDockerService ovsDockerService;
@Autowired
TcService tcService;
DockerContainer dockerContainer1 = null; DockerContainer dockerContainer1 = null;
DockerContainer dockerContainer2 = null; DockerContainer dockerContainer2 = null;
...@@ -145,6 +149,20 @@ public class InDockerTests { ...@@ -145,6 +149,20 @@ public class InDockerTests {
} }
@Test
public void testTcLoss() {
// 查看未加限制的网络情况
dockerService.execInDocker(dockerContainer1.getId(), "tc qdisc add dev eth1 root netem loss 10%");
LOG.info("10%丢包率:" + testLoss());
}
public String testLoss() {
// 需要安装mtr
String cmd = "mtr -r -c 30 -s 1024 10.1.100.2";
return dockerService.execInDocker(dockerContainer2.getId(), cmd);
}
@Test @Test
public void testTcQos() { public void testTcQos() {
// 测试网络带宽 // 测试网络带宽
...@@ -232,6 +250,31 @@ public class InDockerTests { ...@@ -232,6 +250,31 @@ public class InDockerTests {
} }
System.out.println(result); System.out.println(result);
} }
/**
* 这里主要测试接口限速,以及统计实时流量,需要外部辅助执行其他命令
*/
@Test
public void testTCService() {
// 限速
System.out.println(tcService.addQos(dockerContainer2.getId(), "4mbit", "400ms"));
//dockerService.execInDocker(dockerContainer2.getId(), "tc qdisc add dev eth1 root tbf rate 1mbit limit 10k burst 10k mtu 5000");
//dockerService.execInDocker(dockerContainer1.getId(), "tc qdisc add dev eth1 root handle 1: htb default 12");
//dockerService.execInDocker(dockerContainer1.getId(), "tc class add dev eth1 parent 1: classid 1:12 htb rate 1kbit");
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println(tcService.networkUsage(dockerContainer2.getId()));
}
}
}).start();
pingTest();
}
@After @After
public void close() { public void close() {
// 清除Docker // 清除Docker
......
...@@ -37,6 +37,13 @@ ...@@ -37,6 +37,13 @@
<artifactId>spring-test</artifactId> <artifactId>spring-test</artifactId>
<version>5.1.3.RELEASE</version> <version>5.1.3.RELEASE</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies> </dependencies>
</project> </project>
\ No newline at end of file
...@@ -88,5 +88,5 @@ public interface DockerService { ...@@ -88,5 +88,5 @@ public interface DockerService {
String execInDocker(String containerId, String args); String execInDocker(String containerId, String args);
String execInDocker(String containerId, String... args); String execInDocker(String containerId, String[] args);
} }
package top.ninwoo.utils.service;
/**
* @Author joliu
* @Description
* @Date Create in 上午10:07 2019/11/4
*/
public interface NetworkMonitorService {
}
package top.ninwoo.utils.service;
/**
* @Author joliu
* @Description
* @Date Create in 下午3:19 2019/11/1
*/
public interface TcService {
boolean addQos(String containerId, String maxRate, String latency);
boolean delQos(String containerId);
float networkUsage(String containerId);
}
package top.ninwoo.utils.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.ninwoo.utils.service.NetworkMonitorService;
import top.ninwoo.utils.util.DockerUtils;
/**
* @Author joliu
* @Description
* @Date Create in 上午10:07 2019/11/4
*/
@Service
public class NetworkMonitorServiceImpl implements NetworkMonitorService {
@Autowired
DockerUtils dockerUtils;
public double testLoss(String containerId, String targetIp) {
String cmd = "mtr -r -c 30 -s 1024 " + targetIp;
String result = dockerUtils.execInDocker(containerId, targetIp);
// parse result
System.out.println(result);
return 0.0;
}
}
package top.ninwoo.utils.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.ninwoo.utils.service.TcService;
import top.ninwoo.utils.util.DockerUtils;
import top.ninwoo.utils.util.TcUtils;
import java.io.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* @Author joliu
* @Description
* @Date Create in 下午3:34 2019/11/1
*/
@Service
public class TcServiceImpl implements TcService {
// 这里需要设计成有状态的
private ConcurrentHashMap<String, Integer> qosMap = new ConcurrentHashMap<>();
@Autowired
TcUtils tcUtils;
@Autowired
DockerUtils dockerUtils;
@Override
public boolean addQos(String containerId, String maxRate, String latency) {
// 添加到map中
qosMap.put(containerId, Integer.parseInt(maxRate.substring(0, maxRate.length() - 4)));
return tcUtils.addQos(containerId, maxRate, latency);
}
@Override
public boolean delQos(String containerId) {
return tcUtils.delQos(containerId);
}
@Override
public float networkUsage(String containerId) {
// TODO: TOTALBAND需要根据具体情况进行设置
System.out.println("开始收集带宽率");
float netUsage = 0.0f;
String command = "cat /proc/net/dev";
//第一次采集流量数据
long startTime = System.currentTimeMillis();
String[] lines = dockerUtils.execInDocker(containerId, command.split(" ")).split("\n");
int i = 0;
long inSize1 = 0, outSize1 = 0;
while(i < lines.length){
String line = lines[i++];
line = line.trim();
if(line.startsWith("eth1")){
System.out.println(line);
String[] temp = line.split("\\s+");
//System.out.println("temp: "+temp.length+"temp[0]="+temp[0]);
//这里可能因为不同操作系统 展示的结果不同,导致下标不同,
//自己对照 cat /proc/net/dev 该指令执行后展示出的结构 找到Receive bytes 是数组里第几个元素,替换下标即可
inSize1 = Long.parseLong(temp[1]); //Receive bytes,单位为Byte
outSize1 = Long.parseLong(temp[9]); //Transmit bytes,单位为Byte
break;
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
System.out.println("NetUsage休眠时发生InterruptedException. " + e.getMessage());
System.out.println(sw.toString());
}
//第二次采集流量数据
long endTime = System.currentTimeMillis();
lines = dockerUtils.execInDocker(containerId, command.split(" ")).split("\n");
i = 0;
long inSize2 = 0 ,outSize2 = 0;
while(i < lines.length){
String line = lines[i++];
line = line.trim();
if(line.startsWith("eth1")){
//System.out.println(line);
String[] temp = line.split("\\s+");
//这里数组下标也需要修改
inSize2 = Long.parseLong(temp[1]);
outSize2 = Long.parseLong(temp[9]);
break;
}
}
if(inSize1 != 0 && outSize1 !=0 && inSize2 != 0 && outSize2 !=0){
float interval = (float)(endTime - startTime)/1000;
//网口传输速度,单位为bps
float curRate = (float)(inSize2 - inSize1 + outSize2 - outSize1)*8/(1000000*interval);
int maxRate = 1000;
if(qosMap.containsKey(containerId)) {
maxRate = qosMap.get(containerId);
}
netUsage = curRate/maxRate;
//System.out.println("本节点网口速度为: " + curRate + "Mbps");
//System.out.println("本节点网络带宽使用率为: " + netUsage);
}
return netUsage;
}
}
...@@ -35,6 +35,8 @@ public interface DockerUtils { ...@@ -35,6 +35,8 @@ public interface DockerUtils {
boolean deleteDockerById(String id); boolean deleteDockerById(String id);
String execInDocker(String containerId, String args);
String execInDocker(String containerId, String... args); String execInDocker(String containerId, String... args);
boolean startContainer(String containerId); boolean startContainer(String containerId);
......
package top.ninwoo.utils.util;
/**
* @Author joliu
* @Description
* @Date Create in 上午10:38 2019/11/4
*/
public interface OSUtils {
int disk();
int cpuUsage();
int memoryUsage();
float networkUsage();
}
...@@ -154,7 +154,12 @@ public class DockerUtilsImpl implements DockerUtils { ...@@ -154,7 +154,12 @@ public class DockerUtilsImpl implements DockerUtils {
} }
@Override @Override
public String execInDocker(String containerId, String... args) { public String execInDocker(String containerId, String args) {
return execInDocker(containerId, args.split(" "));
}
@Override
public String execInDocker(String containerId, String[] args) {
String result = ""; String result = "";
try { try {
String id = dockerClient.execCreate(containerId, args, DockerClient.ExecCreateParam.attachStdout(), String id = dockerClient.execCreate(containerId, args, DockerClient.ExecCreateParam.attachStdout(),
......
package top.ninwoo.utils.util.impl;
import org.apache.commons.io.FileSystemUtils;
import top.ninwoo.utils.util.OSUtils;
import top.ninwoo.utils.util.Utils;
import java.io.*;
import java.util.*;
/**
* @Author joliu
* @Description
* @Date Create in 上午10:38 2019/11/4
*/
@Utils
public class OSUtilsImpl implements OSUtils {
float TotalBandwidth = 20;
/**
* 查看宿主机硬盘资源
* @return
*/
@Override
public int disk() {
try {
Long total = FileSystemUtils.freeSpaceKb("/home");
double disk = (double) total / 1024 / 1024;
return (int) disk;
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
/**
* 功能:获取Linux系统cpu使用率
* */
@Override
public int cpuUsage() {
try {
Map<?, ?> map1 = cpuinfo();
Thread.sleep(5 * 1000);
Map<?, ?> map2 = cpuinfo();
long user1 = Long.parseLong(map1.get("user").toString());
long nice1 = Long.parseLong(map1.get("nice").toString());
long system1 = Long.parseLong(map1.get("system").toString());
long idle1 = Long.parseLong(map1.get("idle").toString());
long user2 = Long.parseLong(map2.get("user").toString());
long nice2 = Long.parseLong(map2.get("nice").toString());
long system2 = Long.parseLong(map2.get("system").toString());
long idle2 = Long.parseLong(map2.get("idle").toString());
long total1 = user1 + system1 + nice1;
long total2 = user2 + system2 + nice2;
float total = total2 - total1;
long totalIdle1 = user1 + nice1 + system1 + idle1;
long totalIdle2 = user2 + nice2 + system2 + idle2;
float totalidle = totalIdle2 - totalIdle1;
float cpusage = (total / totalidle) * 100;
return (int) cpusage;
} catch (InterruptedException e) {
e.printStackTrace();
}
return 0;
}
/**
* 内存使用率
* @return
*/
@Override
public int memoryUsage() {
Map<String, Object> map = new HashMap<String, Object>();
InputStreamReader inputs = null;
BufferedReader buffer = null;
try {
inputs = new InputStreamReader(new FileInputStream("/proc/meminfo"));
buffer = new BufferedReader(inputs);
String line = "";
while (true) {
line = buffer.readLine();
if (line == null) {
break;
}
int beginIndex = 0;
int endIndex = line.indexOf(":");
if (endIndex != -1) {
String key = line.substring(beginIndex, endIndex);
beginIndex = endIndex + 1;
endIndex = line.length();
String memory = line.substring(beginIndex, endIndex);
String value = memory.replace("kB", "").trim();
map.put(key, value);
}
}
long memTotal = Long.parseLong(map.get("MemTotal").toString());
long memFree = Long.parseLong(map.get("MemFree").toString());
long memused = memTotal - memFree;
long buffers = Long.parseLong(map.get("Buffers").toString());
long cached = Long.parseLong(map.get("Cached").toString());
double usage = (double) (memused - buffers - cached) / memTotal * 100;
return (int) usage;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
buffer.close();
inputs.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
return 0;
}
public Map<?, ?> cpuinfo() {
InputStreamReader inputs = null;
BufferedReader buffer = null;
Map<String, Object> map = new HashMap<String, Object>();
try {
inputs = new InputStreamReader(new FileInputStream("/proc/stat"));
buffer = new BufferedReader(inputs);
String line = "";
while (true) {
line = buffer.readLine();
if (line == null) {
break;
}
if (line.startsWith("cpu")) {
StringTokenizer tokenizer = new StringTokenizer(line);
List<String> temp = new ArrayList<String>();
while (tokenizer.hasMoreElements()) {
String value = tokenizer.nextToken();
temp.add(value);
}
map.put("user", temp.get(1));
map.put("nice", temp.get(2));
map.put("system", temp.get(3));
map.put("idle", temp.get(4));
map.put("iowait", temp.get(5));
map.put("irq", temp.get(6));
map.put("softirq", temp.get(7));
map.put("stealstolen", temp.get(8));
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
buffer.close();
inputs.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
return map;
}
/**
* 查看该主机的网络情况
* @return
*/
@Override
public float networkUsage() {
// TODO: TOTALBAND需要根据具体情况进行设置
System.out.println("开始收集带宽率");
float netUsage = 0.0f;
Process pro1,pro2;
Runtime r = Runtime.getRuntime();
try {
String command = "cat /proc/net/dev";
//第一次采集流量数据
long startTime = System.currentTimeMillis();
pro1 = r.exec(command);
BufferedReader in1 = new BufferedReader(new InputStreamReader(pro1.getInputStream()));
String line = null;
long inSize1 = 0, outSize1 = 0;
while((line=in1.readLine()) != null){
line = line.trim();
if(line.startsWith("enp6s0")){
System.out.println(line);
String[] temp = line.split("\\s+");
System.out.println("temp: "+temp.length+"temp[0]="+temp[0]);
//这里可能因为不同操作系统 展示的结果不同,导致下标不同,
//自己对照 cat /proc/net/dev 该指令执行后展示出的结构 找到Receive bytes 是数组里第几个元素,替换下标即可
inSize1 = Long.parseLong(temp[1]); //Receive bytes,单位为Byte
outSize1 = Long.parseLong(temp[9]); //Transmit bytes,单位为Byte
break;
}
}
in1.close();
pro1.destroy();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
System.out.println("NetUsage休眠时发生InterruptedException. " + e.getMessage());
System.out.println(sw.toString());
}
//第二次采集流量数据
long endTime = System.currentTimeMillis();
pro2 = r.exec(command);
BufferedReader in2 = new BufferedReader(new InputStreamReader(pro2.getInputStream()));
long inSize2 = 0 ,outSize2 = 0;
while((line=in2.readLine()) != null){
line = line.trim();
if(line.startsWith("enp6s0")){
System.out.println(line);
String[] temp = line.split("\\s+");
//这里数组下标也需要修改
inSize2 = Long.parseLong(temp[1]);
outSize2 = Long.parseLong(temp[9]);
break;
}
}
if(inSize1 != 0 && outSize1 !=0 && inSize2 != 0 && outSize2 !=0){
float interval = (float)(endTime - startTime)/1000;
//网口传输速度,单位为bps
float curRate = (float)(inSize2 - inSize1 + outSize2 - outSize1)*8/(1000000*interval);
netUsage = curRate/TotalBandwidth;
System.out.println("本节点网口速度为: " + curRate + "Mbps");
System.out.println("本节点网络带宽使用率为: " + netUsage);
}
in2.close();
pro2.destroy();
} catch (IOException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
System.out.println("NetUsage发生InstantiationException. " + e.getMessage());
System.out.println(sw.toString());
}
return netUsage;
}
}
...@@ -3,7 +3,9 @@ package top.ninwoo.utils.util.impl; ...@@ -3,7 +3,9 @@ package top.ninwoo.utils.util.impl;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import top.ninwoo.utils.util.DockerUtils; import top.ninwoo.utils.util.DockerUtils;
import top.ninwoo.utils.util.TcUtils; import top.ninwoo.utils.util.TcUtils;
import top.ninwoo.utils.util.Utils;
import java.io.*;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
...@@ -12,6 +14,7 @@ import java.util.Set; ...@@ -12,6 +14,7 @@ import java.util.Set;
* @Description * @Description
* @Date Create in 下午5:20 2019/10/30 * @Date Create in 下午5:20 2019/10/30
*/ */
@Utils
public class TcUtilsImpl implements TcUtils { public class TcUtilsImpl implements TcUtils {
@Autowired @Autowired
...@@ -35,6 +38,7 @@ public class TcUtilsImpl implements TcUtils { ...@@ -35,6 +38,7 @@ public class TcUtilsImpl implements TcUtils {
@Override @Override
public boolean addQos(String containerId, String maxRate, String latency) { public boolean addQos(String containerId, String maxRate, String latency) {
String res = dockerUtils.execInDocker(containerId, "tc qdisc add dev eth1 root tbf rate " + maxRate + " burst 32kbit latency " + latency); String res = dockerUtils.execInDocker(containerId, "tc qdisc add dev eth1 root tbf rate " + maxRate + " burst 32kbit latency " + latency);
//dockerUtils.execInDocker("limit 10k burst 10k mtu 5000")
if(!"".equals(res)) { if(!"".equals(res)) {
return false; return false;
} }
......
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 top.ninwoo.utils.config.DockerConfig;
import top.ninwoo.utils.util.OSUtils;
/**
* @Author joliu
* @Description
* @Date Create in 上午10:45 2019/11/4
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = DockerConfig.class)
public class OsUtilsTests {
@Autowired
OSUtils osUtils;
@Test
public void testDisk() {
System.out.println("Disk:" + osUtils.disk() + "GB");
System.out.println("CPU:" + osUtils.cpuUsage() + "%");
System.out.println("MEM:" + osUtils.memoryUsage() + "%");
int i = 0;
while(i < 10) {
System.out.println("NET:" + osUtils.networkUsage() + "%");
}
}
}
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