1.案例场景
- 系统的用户 CPU 使用率(usr%)过高
- 没有 CPU 使用率高的进程
2.案例环境
- 本地系统:mac
- docker:docker镜像-cpu使用率过高
- 补充:
1.phpfpm容器要给权限
docker run --privileged ...
;
2.进入phpfpm安装检查软件 apt install stress sysstat
;
3.phpfpm内安装perfapt-get install -y linux-perf
3.操作分析
3.1 检查环境正常
在第二个中断,确认Nginx服务器正常启动,并发送100个请求检查Nginx性能
1
2
3
4
5
6
7
8
9
|
# ip地址是虚拟机的ip地址
$ curl http://127.0.0.1:10000/
# 并发 100 个请求测试 Nginx 性能,总共测试 1000 个请求
$ ab -c 100 -n 1000 http://127.0.0.1:10000/
# 打印
...
Requests per second: 130.19 [#/sec] (mean)
Time per request: 768.107 [ms] (mean)
...
|
3.2 压力测试
1
2
|
# 并发请求数为5,请求时间为10分钟(-t 600)
$ b -c 5 -t 600 http://192.168.0.10:10000/
|
3.3 分析
步骤1. 用top观察系统的cpu使用情况
1
2
3
4
5
6
7
8
9
10
11
12
13
|
...
Tasks: 20 total, 6 running, 14 sleeping, 0 stopped, 0 zombie
%Cpu(s): 62.3 us, 24.9 sy, 0.0 ni, 11.2 id, 0.0 wa, 0.0 hi, 1.6 si, 0.0 st
...
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
34256 daemon 20 0 227180 14296 8296 S 3.0 0.7 0:00.19 php-fpm
34261 daemon 20 0 227180 14232 8232 R 2.7 0.7 0:00.18 php-fpm
34269 daemon 20 0 227180 14232 8232 S 2.7 0.7 0:00.18 php-fpm
34272 daemon 20 0 227180 14232 8232 S 2.7 0.7 0:00.18 php-fpm
34283 daemon 20 0 227180 14232 8232 S 2.7 0.7 0:00.17 php-fpm
1 root 20 0 227180 32524 26752 S 0.3 1.6 0:00.57 php-fpm
37036 daemon 20 0 4752 104 0 R 0.0 0.0 0:00.00 stress
|
分析:cpu使用率高,但是进程列表没有大的cpu使用进程,那为什么cou使用率高内?
步骤2. 用pidstat分析进程的CPU使用情况
1
2
3
4
5
6
7
8
|
# 间隔1s输出一组数据(按 Ctrl+C 结束)
$ pidstat 1
# 打印
Linux 4.19.76-linuxkit (78890ee58ed3) 05/29/20 _x86_64_ (4 CPU)
03:10:05 UID PID %usr %system %guest %wait %CPU CPU Command
03:10:06 UID PID %usr %system %guest %wait %CPU CPU Command
|
分析:发现进程的cpu使用率也不高
老炮儿分析:去运行top,观察一会儿,发现6个running状态的进程数,并且观察到php-fpm进程都处于Sleep状态;而处于running状态的进程却是今个stress
步骤3. 找一个stress进程进行分析
在怀疑性能工 具出问题前,最好还是先用其他工具交叉确认一下
1
2
3
4
|
# 分析pid进程cpu
$ pidstat -p <pid>
# 从所有进程中查找PID是pid的进程
$ ps aux | grep <pid>
|
这些进程在不停地重启,要么就是全 新的进程,这无非也就两个原因:
第一个原因,进程在不停地崩溃重启,比如因为段错误、配置错误等等,这时,进程在退出后可能又被监控系统自动重启了。
第二个原因,这些进程都是短时进程,也就是在其他应用内部通过exec调用的外面命令。这些命令一般都只运行很短的时间就会结束,你很难用top这种间隔时间比较长的工具发现(上面的案例,我们碰巧发现了)。
步骤4.pstree显示进程直接的关系
1
2
|
$ pstree | grep stress
php-fpm-+-4*[php-fpm---sh---stress---stress]
|
分析:stress是被php-fpm调用的子进程,并且进程数量不止一个(这里是 3 个)。找到父进程后,我们能进入app的内部分析了
1
2
3
4
5
6
|
# 拷贝源码到本地
$ docker cp phpfpm:/app .
# grep 查找看看是不是有代码在调用 stress 命令
$ grep stress -r app
app/index.php:// fake I/O with stress (via write()/unlink()).
app/index.php:$result = exec("/usr/local/bin/stress -t 1 -d 1 2>&1", $output, $status);
|
可以看到,果然是源码直接调用了stress,然后修改问题
3.4其他工具
perf 和 execsnoop
1
2
3
4
|
# 记录性能事件,等待大约 15 秒后按 Ctrl+C 退出
$ perf record -g
# 查看报告
$ perf report
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
Samples: 274K of event 'cpu-clock', Event count (approx.): 68743250000
Self Command Shared Object Symbol
- 17.48% stress libc-2.28.so [.] random ◆
- 0.81% random ▒
- 0.74% 0xffffffffa8800a34 ▒
- 0.58% 0xffffffffa8003ad5 ▒
0xffffffffa8003358 ▒
- 15.19% stress libc-2.28.so [.] random_r ▒
- 0.69% random_r ▒
- 0.62% 0xffffffffa8800a34 ▒
- 0.50% 0xffffffffa8003ad5 ▒
0xffffffffa8003358 ▒
+ 0.00% swapper [unknown] [k] 0xffffffffa8800088 ▒
+ 0.00% swapper [unknown] [k] 0xffffffffa8003c87
|
4.总结
- 分析性能问题时,最好能多工具结合分析
vmstat pidstat top ps pstree execsnoop
- 发现无法解释的cpu使用情况时:
- 首先要想到有可能是短时应用导致的问题。
- 应用里直接调用了其他二进制程序,这些程序通常运行时间比较短,通过top等工具也不容易发现。
- 应用本身在不停地崩溃重启,而启动过程的资源初始化,很可能会占用相当多的 CPU。