機器配置:2 CPU,8GB 內存 預先安裝 docker、sysstat、perf等工具php
[root@luoahong ~]# docker -v Docker version 18.09.1, build 4c52b90 [root@luoahong ~]# rpm -qa|grep sysstat sysstat-12.1.2-1.x86_64
機器配置:1 CPU,2GB 內存 預先安裝ab 等工具mysql
[root@nfs ~]#yum -y install httpd-tools [root@nfs ~]# ab -V This is ApacheBench, Version 2.3 <$Revision: 1430300 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/
docker run --name nginx -p 10000:80 -itd feisky/nginx:sp $ docker run --name phpfpm -itd --network container:nginx feisky/php-fpm:sp
測試nginx是否啓動linux
# 192.168.118.97 是第一臺虛擬機的 IP 地址 $ curl http://192.168.118.97:10000/ It works!
性能測試nginx
# 併發 100 個請求測試 Nginx 性能,總共測試 1000 個請求 $ ab -c 100 -n 1000 http://192.168.118.97:10000/ This is ApacheBench, Version 2.3 <$Revision: 1706008 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, ... Requests per second: 87.86 [#/sec] (mean) Time per request: 1138.229 [ms] (mean) ...
繼續壓力測試git
ab -c 5 -t 600 http://192.168.118.97:10000/
[root@luoahong ~]# pidstat 1 Linux 3.10.0-957.5.1.el7.x86_64 (luoahong) 05/04/2019 _x86_64_ (2 CPU) 03:41:55 PM UID PID %usr %system %guest %wait %CPU CPU Command 03:41:56 PM 0 3 0.00 2.94 0.00 0.00 2.94 0 ksoftirqd/0 03:41:56 PM 0 9 0.00 6.86 0.00 27.45 6.86 0 rcu_sched 03:41:56 PM 0 14 0.00 15.69 0.00 9.80 15.69 1 ksoftirqd/1 03:41:56 PM 0 7500 4.90 2.94 0.00 0.98 7.84 0 vmtoolsd 03:41:56 PM 0 9451 0.00 1.96 0.00 0.00 1.96 1 dockerd 03:41:56 PM 27 9928 0.00 0.98 0.00 0.00 0.98 0 mysqld 03:41:56 PM 0 10133 0.98 0.00 0.00 0.00 0.98 1 containerd-shim 03:41:56 PM 0 10804 0.00 0.98 0.00 4.90 0.98 1 kworker/1:0 03:41:56 PM 0 10835 0.98 3.92 0.00 0.00 4.90 1 containerd-shim 03:41:56 PM 101 10891 0.00 5.88 0.00 15.69 5.88 0 nginx 03:41:56 PM 1 84378 0.98 2.94 0.00 3.92 3.92 0 php-fpm 03:41:56 PM 1 84388 0.00 1.96 0.00 3.92 1.96 1 php-fpm 03:41:56 PM 1 84395 0.98 0.98 0.00 4.90 1.96 1 php-fpm 03:41:56 PM 1 84411 0.00 0.98 0.00 3.92 0.98 0 php-fpm 03:41:56 PM 1 84413 0.00 1.96 0.00 8.82 1.96 1 php-fpm 03:41:56 PM 0 102735 0.00 0.98 0.00 0.00 0.98 1 pidstat
你有沒有發現,nginx和全部的PHP-FPM都處於sleep狀態,二真正處於Running(R)狀態的,倒是幾個 stress 進程,這幾個stree比較奇怪,須要咱們作進一步的分析github
[root@luoahong perf-tools]# pidstat -p 24226 Linux 3.10.0-957.5.1.el7.x86_64 (luoahong) 05/04/2019 _x86_64_ (2 CPU) 03:47:45 PM UID PID %usr %system %guest %wait %CPU CPU Command
奇怪、竟然沒有任何輸出。難道是pidstat命令出問題了嗎?在懷疑西能工具出問題前,最好仍是先用其餘工具交叉確認一下sql
[root@luoahong perf-tools]# ps aux|grep 24226 root 66566 0.0 0.0 112708 980 pts/0 S+ 15:46 0:00 grep --color=auto 24226
仍是沒有輸出,如今終於發現問題,原來這個進程已經不存在了,因此pidstat就沒有任何輸出,既然進程都沒了docker
那西能問題應該跟着沒了吧。咱們在top命令確認一下;apache
top ... %Cpu(s): 80.9 us, 14.9 sy, 0.0 ni, 2.8 id, 0.0 wa, 0.0 hi, 1.3 si, 0.0 st ... PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 6882 root 20 0 12108 8360 3884 S 2.7 0.1 0:45.63 docker-containe 6947 systemd+ 20 0 33104 3764 2340 R 2.7 0.0 0:47.79 nginx 3865 daemon 20 0 336696 15056 7376 S 2.0 0.2 0:00.15 php-fpm 6779 daemon 20 0 8184 1112 556 R 0.3 0.0 0:00.01 stress ...
但是,剛剛看到的stree進程不存在了,怎麼還在運行呢?原來此次stree進程的pid跟前面不同了,原來的pid不見了如今的是6779api
進程的 PID 在變,這說明什麼呢?在我看來要麼是這些進程在不停地重啓,要麼就是全新的進程,這無非也就兩個緣由
第一緣由:進程在不停地崩潰重啓,好比由於段錯誤、配置錯誤等等這時,進程在退出後可能又被監控系統自動重啓了。
第二緣由:這些進程都是短時進程,也就是在其餘應用內部經過 exec 調用的外面命令。這些命令通常都只運行很短的時間就會結束,你很難用 top 這種間隔時間比較長的工具發現(上面的案例,咱們碰巧發現了)
[root@luoahong ~]# pstree | grep stress | | | |-2*[php-fpm---sh---stress---stress] | | | |-php-fpm---sh---stress
查找是否是代碼在調用stree命令
# 拷貝源碼到本地 $ 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);
找到了,果真是app/index.php
cat app/index.php <?php // fake I/O with stress (via write()/unlink()). $result = exec("/usr/local/bin/stress -t 1 -d 1 2>&1", $output, $status); if (isset($_GET["verbose"]) && $_GET["verbose"]==1 && $status != 0) { echo "Server internal error: "; print_r($output); } else { echo "It works!"; } ?>
[root@nfs ~]# curl http://192.168.118.97:10000/?verbose=1 Server internal error: Array ( [0] => stress: info: [103660] dispatching hogs: 0 cpu, 0 io, 0 vm, 1 hdd [1] => stress: FAIL: [103661] (563) mkstemp failed: Permission denied [2] => stress: FAIL: [103660] (394) <-- worker 103661 returned error 1 [3] => stress: WARN: [103660] (396) now reaping child worker processes [4] => stress: FAIL: [103660] (400) kill error: No such process [5] => stress: FAIL: [103660] (451) failed run completed in 0s )
從這裏咱們能夠猜想,正式因爲權限錯誤,大量的stress進程在啓動是初始化失敗,進而致使用戶CPU使用率的升高
perf record -g docker cp perf.data phpfpm:/tmp docker exec -i -t phpfpm bash
cd /tmp/ apt-get update && apt-get install -y linux-perf linux-tools procps perf_4.9 report
execsnoop 就是一個專爲短時進程設計的工具它經過 ftrace 實時監控進程的 exec() 行爲,並輸出短時進程的基本信息,
包括進程 PID、父進程 PID、命令行參數以及執行的結果。
用 execsnoop 監控上述案例,就能夠直接獲得 strress 進程的父進程 PID 以及它的命令行參數,並能夠發現大量的 stress 進程在不停啓動:
git clone --depth 1 https://github.com/brendangregg/perf-tools cd perf-tools/ [root@luoahong perf-tools]# ./bin/execsnoop Tracing exec()s. Ctrl-C to end. Instrumenting sys_execve PID PPID ARGS 70342 70322 gawk -v o=1 -v opt_name=0 -v name= -v opt_duration=0 [...] 70344 50765 <...>-70344 [001] d... 2372.510629: execsnoop_sys_execve: (SyS_execve+0x0/0x30) 70343 70341 cat -v trace_pipe 70340 0 /usr/local/bin/stress -t 1 -d 1 70346 70339 /usr/local/bin/stress -t 1 -d 1 70347 70344 /usr/local/bin/stress -t 1 -d 1 70351 50796 <...>-70351 [000] d... 2372.553884: execsnoop_sys_execve: (SyS_execve+0x0/0x30) 70352 50775 <...>-70352 [000] d... 2372.555010: execsnoop_sys_execve: (SyS_execve+0x0/0x30) 70353 70351 /usr/local/bin/stress -t 1 -d 1 70355 50776 <...>-70355 [000] d... 2372.557869: execsnoop_sys_execve: (SyS_execve+0x0/0x30) 70357 70355 /usr/local/bin/stress -t 1 -d 1 70356 70352 /usr/local/bin/stress -t 1 -d 1
execsnoop所用的ftrace是一種經常使用的動態追蹤技術,通常用於分析linux內核的運行時爲
yum install psmisc
若是碰到很差解釋的CPU問題時,好比現象:
經過top觀察CPU使用率很高,可是看下面的進程的CPU使用率好像很正常,經過pidstat命令查看cpu也很正常。但經過top查看task數量不正常,處於R狀態的進程是可疑點。
首先要想到多是短期的應用致使的問題,以下面的兩個:(1)應用裏直接調用了其餘二進制程序,這些程序一般運行時間比較短,經過top等工具發現不了(2)應用自己在不停地崩潰重啓,而啓動過程的資源初始化,極可能會佔用不少CPU資源