03 监控容器cpu真实使用率

一 在容器内无法通过top命令获取真实cpu使用率

当容器云平台中一些节点出现负载过高、导致应用程序异常时,一个主要的解决方案就是找出对cpu占用过高的进程。容器云平台主要跑的都是容器进程,如何查看容器进程对cpu的真实使用率就成了一件重要的事情。

在宿主机我们可以通过top命令查看,但是在容器里,你通过top命令是无法查看到容器本身总共占用了多cpu资源的,看到的依然是宿主机的状态

我们进入容器内执行top查看:docker run -ti –name test centos:7 sh

发现容器内进程消耗0.7+0.7+0.3+0.0,而容器内的sh进程与top进程都没有消耗这么多cpu,这就验证了我们的说法:在容器内是无法通过top命令获取容器对cpu的占用率的

既然top命令做不到,那么就需要我们自己开发工作来获取容器对cpu的真实占用率,具体怎么获取?先来储备一个知识,请看下一小节

二 获取cpu的真实使用率

2.1 获取单个进程对cpu的使用率

先来储备两个非常重要的知识

  • 1、进程对cpu的使用率,是以单颗cpu作为分母的,所以我们从结果上看,如果某一个时间段内一个进程对cpu的使用率为100%,那么1*100%得到1,代表这段时间内该进程使用了1颗CPU,如果为200%,同样是1颗cpu去乘以该比例,得到2,代表这段时间内该进程占用了2颗cpu

  • 2、进程从启动那一刻开始linux操作系统就会累积该进程对cpu的资源的占用,这跟你物理机有几颗cpu无关,因为是累积的,所以一个进程在某个时间点可能累积使用过的cpu个数为10,也可能是100,而你的宿主机cpu可能就只有4颗

具体来说负责记录下进程对cpu资源累积占用的是linux系统中proc文件系统

top命令就是通过查看proc文件系统中每个进程对应stat文件中的2个数值来完成统计的

# 1、测试脚本
[root@test04 ~]# cat a.sh 
i=0
while true;
do
    let i++
done
[root@test04 ~]# 

# 2、执行
[root@test04 ~]# sh a.sh &
[1] 43157

# 3、查看
[root@test04 ~]# cat /proc/43157/stat | awk '{print $14,$15}'
1314 14

cat /proc/19838/stat 的内容有50多项,包括进程pid、名字、运行状态、ppid、优先级、内存使用等。要统计cpu使用率,主要关注第14项utime与第15项目stime

  • 1、utime代表进程的用户态部分在linux系统调度中获取的cpu的ticks

  • 2、stime代表进程的内核态部分在linux系统调度中获取的cpu的ticks

ticks是linux系统的一个时间单位,类似于秒、毫秒一样的时间单位,只不过在linux中一个tick代表一次中断的周期,这个周期需要耗费的时间由中断频率HZ决定,HZ在linux系统中默认为100,可以用如下命令查看

[root@test04 ~]# getconf CLK_TCK # HZ为100代表1s内发生100次中断,
100

那想知道一个tick具体代表多长时间就是:1/100 秒,即一次中断耗费的时间是1/100秒,也就是一个tick所代表的的时间。如果utime等于150ticks,就相当于150*1/100=1.5秒,代表进程从启动那一刻到现在总共在用户态运行了1.5秒钟。

那如何统计进程对cpu的占用率呢,公式如下

进程的 CPU 使用占比 =((utime_2 – utime_1) + (stime_2 – stime_1)) / (HZ * et * 1 )

上述结果为一个小数,想要得到百分率,需要乘以100,如下
进程的 CPU 使用百分率 = ((utime_2 – utime_1) + (stime_2 – stime_1)) * 100 / (HZ * et * 1 )

et为统计的时间间隔,如果为10s,那么我们需要在开始获取一下utime_1与stime_1

然后等待10s后,再次获取,即utime_2与stime_2

那么((utime_2 – utime_1) + (stime_2 – stime_1))代表的就是10s内,该进程累积对占用的用户态与内核态的ticks总数

(HZ et 1 )中1代表1颗cpu、et代表时间间隔,HZ代表中断频率,ticks是按照固定频率发生的,在linux系统中默认HZ为100,代表1秒钟是100次,所以(HZ et 1 )即(100 10 1)

综上,上面的公司我们可以简化为

进程的 CPU 使用百分率 =(某段时间内进程占内核态与用户态ticks/ 该段时间内单个 CPU 总 ticks)*100.0

最后乘以那个100代表转换为百分比

补充:一个cpu的完整工作时间,可能服务过多个进程,如下图颜色标注代表cpu服务过3个进程,红色框代表的进程可能占用的只是tick3、tick6、tick7这三个时间片,那么该段时间内,红色框进程对cpu的占用率(注意对cpu的占用率一定统计的是单颗)就是3/7

举例

我们用命令查看启动进程的cpu占用率Wie7.6

[root@test04 ~]# sh a.sh &
[1] 63214
[root@test04 ~]# ps aux |head -1
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
[root@test04 ~]# ps aux |grep 63214 |grep a.sh
root      63214  7.6  0.1 113552  3316 pts/0    S    12:30   1:43 sh a.sh

然后我们自己编写脚本来统计该进程对cpu的占用率

utime1=$(cat /proc/63214/stat | awk '{print $14}')
stime1=$(cat /proc/63214/stat | awk '{print $15}')

sleep 10                                 # 等待10s后

utime2=$(cat /proc/63214/stat | awk '{print $14}')
stime2=$(cat /proc/63214/stat | awk '{print $15}')

user_ticks=$((utime2-utime1))
sys_ticks=$((stime2-stime1))
process_total_ticks=$((user_ticks+sys_ticks))

cpu_total_ticks=$((100 * 10 * 1))

echo ${process_total_ticks} / ${cpu_total_ticks} | bc -l 

输出.07600000000000000000,与我们用ps命令或者top命令看到的7.6一致

2.2 统计整个系统对cpu的使用率

top命令是如何统计出一个cpu上,所有的us进程对整颗cpu的占用率,以及sys、ni、id、wa、hi、si、st各自对本颗cpu的占用率呢?

联系管理员微信tutu19192010,注册账号

上一篇
下一篇
Copyright © 2022 Egon的知识星球 egonlin.com 版权所有 帮助IT小伙伴学到真正的技术