综述:这可能是大多数程序员最不愿意看到的指标,据我了解若是想简单粗暴解决问题唯有kill, 但是kill的一瞬间可能并不是程序处理业务的安全点,准确点说任何时候都不能kill,因为你也不知道业务处理到哪了,我们可能做得就是尽量避免损失
启发之路
你脑海中是否有过忽然之间会把两个不相干的事情联系在一起,然后若有所得,这次启发来自于最近在学习Docker的基本原理——Linux Cgroups(资源控制组)
曲线救"国"
通过限制进程的CPU资源来实现降低其CPU利用率
进程的哪些资源被控制?在哪里被控制的?
进程资源被统一管理到一个资源控制组内,其路径为:/sys/fs/cgroup/ ,都包括:设备、cup、内存等等,每一种资源都以文件夹的形式呈现
你可以进入任意一个资源文件夹,创一个一个属于自己的资源限制组(文件夹),那么系统自动为你生成该组对应的资源的限定文件,举例
-
在对应的资源组里创建文件夹,查看其目录结构
-
对比两个文件夹内对资源限定的文件
结论:发现系统资源控制组内的memory文件夹内容与新创建的memory_test文件夹内容一致(这里有一种"父子"文件夹的味道了)
开始曲线救"国"
系统:centos7
环境:gcc version 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC)
说明:该操作需要创建多个linux session连接协同作战
- 我们需要创建一个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;
}
- 编译(在cup.c当前路径下)
[root@localhost ~]# g++ cpu.c -o cpu.out -std=c++11 -pthread -D_GLIBCXX_USE_NANOSLEEP
- 在/sys/fs/cgroup/cpu目录下创建test_cpu目录
[root@localhost cpu]# mkdir test_cpu
- 修改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资源
- 启动 cup.out,此时你电脑的风扇开始疯狂咆哮
[root@localhost 桌面]# ./cpu.out
thread: test_cpu start
#此时会一直阻塞 除非你kill掉该进程
- top命令观察
- 将该进程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]#
- 风扇回到了往日的平静
课后作业
当进程启动的时候,请查看 cat /sys/fs/cgroup/cpu/cgroup.procs 是否存在该进程ID?
当我将该进程ID加入到test_cpu文件夹内的cgroup.procs文件里时候,请再次查看cat /sys/fs/cgroup/cpu/cgroup.procs 是否存在?
这是为什么?
总结
这是一次治标不治本的实践,其意义在于出现这种情况或许我们能够挣扎一下,保证其他应用还能有效运行
温馨提示
如果你按照步骤来玩恭喜你只成功了一半,因为另外一半就是我似乎无法删除我创建的资源限制组,哈哈~~
欢迎大家多多评论,一起学习,一起进步