背景:项目需要做基于CPU利用率的负载均衡,需要获取CPU利用率,目前有物理机和docker机两种机器;
物理机获取CPU利用率
原理:分两次读取/proc/stat文件内容,利用CPU的idle和usage比值,计算CPU利用率;
struct CpuInfo {
unsigned int total;
unsigned int idle;
};
bool getCpuInfo(const std::string& file, CpuInfo& info){
FILE * fp=NULL;
fp=fopen(file.c_str(), "r");
if(fp == NULL){
printf("open %s fail\n", file.c_str());
return false;
}
char data[1024]={'\0'};
fgets(data,1024, fp);
char name[32] = {'\0'};
unsigned int user, nice, sys, idle, iowait, irq, softirq, steal;
sscanf(data,"%s %u %u %u %u %u %u %u %u", name, &user, &nice, &sys, &idle, &iowait, &irq, &softirq, &steal); fclose(fp);
info.total = user + nice + sys + idle + iowait + irq + softirq + steal; // 总的CPU时间
info.idle = idle + iowait; // 空闲CPU时间
return true;
}
int GetCpuUsage() {
CpuInfo info1;
CpuInfo info2;
getCpuInfo("/proc/stat", info1);
sleep(1);
getCpuInfo("/proc/stat", info2);
// 计算CPU利用率
unsigned int usage = (info2.total - info2.idle) - (info1.total - info1.idle);
int cpu_utilize = (usage * 100) / (info2.total - info1.total);
return cpu_utilize;
}
Docker机CPU利用率获取
原理:读取/sys/fs/cgroup/cpu/cpu.cfs_quota_us和/sys/fs/cgroup/cpu/cpu.cfs_period_us文件内容,计算出docker机分配的CPU核数;/sys/fs/cgroup/cpu/cpuacct.usage文件内容是容器消耗cpu的时间的累积值,单位是纳秒,前后两次采集cpuacct.usage的差值作为分子,两次采集的时间间隔*核数作为分母;
#!/bin/sh
# 1. 计算CPU核数
quoto=`cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us`
period=`cat /sys/fs/cgroup/cpu/cpu.cfs_period_us`
cpu_core=`expr $quoto / $period`
time_diff=10
# 2. 第一次读取cpuacct.usage
usage_1=`cat /sys/fs/cgroup/cpu/cpuacct.usage`
sleep $time_diff #等待一段时间
# 3. 第二次读取cpuacct.usage
usage_2=`cat /sys/fs/cgroup/cpu/cpuacct.usage`
# 4. 计算CPU利用率
usage_diff=$((usage_2-$usage_1))
usage=$((usage_diff/cpu_core/time_diff/10000000))
echo "cpu_usage:$usage"