CPU99%除了kill,还能做啥?

789 阅读3分钟

综述:这可能是大多数程序员最不愿意看到的指标,据我了解若是想简单粗暴解决问题唯有kill, 但是kill的一瞬间可能并不是程序处理业务的安全点,准确点说任何时候都不能kill,因为你也不知道业务处理到哪了,我们可能做得就是尽量避免损失

启发之路

你脑海中是否有过忽然之间会把两个不相干的事情联系在一起,然后若有所得,这次启发来自于最近在学习Docker的基本原理——Linux Cgroups(资源控制组)

请移步:juejin.cn/post/696363…

曲线救"国"

通过限制进程的CPU资源来实现降低其CPU利用率

进程的哪些资源被控制?在哪里被控制的?

进程资源被统一管理到一个资源控制组内,其路径为:/sys/fs/cgroup/ ,都包括:设备、cup、内存等等,每一种资源都以文件夹的形式呈现

WX20210519-064537@2x11.png

你可以进入任意一个资源文件夹,创一个一个属于自己的资源限制组(文件夹),那么系统自动为你生成该组对应的资源的限定文件,举例

  1. 在对应的资源组里创建文件夹,查看其目录结构 WX20210519-065553@2x22.png

  2. 对比两个文件夹内对资源限定的文件

WX20210519-065507@2x33.png WX20210519-065703@2x44.png

结论:发现系统资源控制组内的memory文件夹内容与新创建的memory_test文件夹内容一致(这里有一种"父子"文件夹的味道了)

开始曲线救"国"

系统:centos7

环境:gcc version 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC)

说明:该操作需要创建多个linux session连接协同作战

  1. 我们需要创建一个cup.c模拟一个进程,该进程可以是CUP的利用率飙到99%
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <thread>

void test_cpu() {
    printf("thread: test_cpu start\n");
    int total = 0;
    while (1) {
        ++total;
    }
}


int main(int argc, char** argv) {
    std::thread t1(test_cpu);
    t1.join();
    return 0;
}


  1. 编译(在cup.c当前路径下)
[root@localhost ~]# g++ cpu.c -o cpu.out -std=c++11 -pthread -D_GLIBCXX_USE_NANOSLEEP 
  1. 在/sys/fs/cgroup/cpu目录下创建test_cpu目录
[root@localhost cpu]# mkdir test_cpu
  1. 修改test_cpu文件内cpu.cfs_period_us、cpu.cfs_quota_us
[root@localhost test_cpu]# sudo echo 100000 > cpu.cfs_period_us 
[root@localhost test_cpu]# sudo echo 20000 > cpu.cfs_quota_us 
#解释 :
#cpu.cfs_period_us = 100000 把cup分成100000份
#cpu.cfs_quota_us =20000 当前资源组内的cup资源最多占20000份
#也就是说把某个进程限制在了该组内其最多利用20%左右的cup资源
  1. 启动 cup.out,此时你电脑的风扇开始疯狂咆哮
[root@localhost 桌面]# ./cpu.out 
thread: test_cpu start
#此时会一直阻塞 除非你kill掉该进程
  1. top命令观察

WX20210519-191006@2x55.png

  1. 将该进程ID加入到test_cup资源限制组内
[root@localhost ~]# cd /sys/fs/cgroup/cpu/test_cpu/
[root@localhost test_cpu]# sudo echo 16759 > cgroup.procs 
[root@localhost test_cpu]# 
  1. 风扇回到了往日的平静

WX20210519-191250@2x66.png

课后作业

当进程启动的时候,请查看 cat /sys/fs/cgroup/cpu/cgroup.procs 是否存在该进程ID?

当我将该进程ID加入到test_cpu文件夹内的cgroup.procs文件里时候,请再次查看cat /sys/fs/cgroup/cpu/cgroup.procs 是否存在?

这是为什么?

大大的问号.jpeg

总结

这是一次治标不治本的实践,其意义在于出现这种情况或许我们能够挣扎一下,保证其他应用还能有效运行

温馨提示

如果你按照步骤来玩恭喜你只成功了一半,因为另外一半就是我似乎无法删除我创建的资源限制组,哈哈~~

dksmile.jpeg

欢迎大家多多评论,一起学习,一起进步