上一節(jié)我講了 CPU 使用率是什么避消,并通過一個案例教你使用 top、vmstat召夹、pidstat 等工具岩喷,排查高 CPU 使用率的進程,然后再使用 perf top 工具监憎,定位應用內(nèi)部函數(shù)的問題纱意。不過就有人留言了,說似乎感覺高 CPU 使用率的問題鲸阔,還是挺容易排查的偷霉。
那是不是所有 CPU 使用率高的問題,都可以這么分析呢褐筛?我想类少,你的答案應該是否定的。
回顧前面的內(nèi)容渔扎,我們知道硫狞,系統(tǒng)的 CPU 使用率,不僅包括進程用戶態(tài)和內(nèi)核態(tài)的運行晃痴,還包括中斷處理残吩、等待 I/O 以及內(nèi)核線程等。所以愧旦,當你發(fā)現(xiàn)系統(tǒng)的 CPU 使用率很高的時候世剖,不一定能找到相對應的高 CPU 使用率的進程。
今天笤虫,我就用一個 Nginx + PHP 的 Web 服務的案例旁瘫,帶你來分析這種情況祖凫。
案例分析
你的準備
今天依舊探究系統(tǒng) CPU 使用率高的情況,所以這次實驗的準備工作酬凳,與上節(jié)課的準備工作基本相同惠况,差別在于案例所用的 Docker 鏡像不同。
本次案例還是基于 Centos7宁仔,同樣適用于其他的 Linux 系統(tǒng)稠屠。我使用的案例環(huán)境如下所示:機器配置:2 CPU,8GB 內(nèi)存預先安裝 docker翎苫、sysstat权埠、perf、ab 等工具
前面我們講到過煎谍,ab(apache bench)是一個常用的 HTTP 服務性能測試工具攘蔽,這里同樣用來模擬 Nginx 的客戶端。由于 Nginx 和 PHP 的配置比較麻煩呐粘,我把它們打包成了兩個Docker 鏡像 满俗,這樣只需要運行兩個容器,就可以得到模擬環(huán)境作岖。
注意唆垃,這個案例要用到兩臺虛擬機,如下圖所示:
你可以看到痘儡,其中一臺用作 Web 服務器辕万,來模擬性能問題;另一臺用作 Web 服務器的客戶端谤辜,來給 Web 服務增加壓力請求蓄坏。使用兩臺虛擬機是為了相互隔離,避免“交叉感染”丑念。
接下來涡戳,我們打開兩個終端,分別 SSH 登錄到兩臺機器上脯倚,并安裝上述工具渔彰。
同樣注意,下面所有命令都默認以 root 用戶運行推正,如果你是用普通用戶身份登陸系統(tǒng)恍涂,請運行 sudo su root 命令切換到 root 用戶。
走到這一步植榕,準備工作就完成了再沧。接下來,我們正式進入操作環(huán)節(jié)尊残。
操作和分析
首先炒瘸,我們在第一個終端淤堵,執(zhí)行下面的命令運行 Nginx 和 PHP 應用:
$ docker run --name nginx -p 10000:80 -itd feisky/nginx:sp
$ docker run --name phpfpm -itd --network container:nginx feisky/php-fpm:sp
然后,在第二個終端顷扩,使用 curl 訪問 http://[VM1 的 IP]:10000拐邪,確認 Nginx 已正常啟動。你應該可以看到 It works! 的響應隘截。
# 192.168.0.10是第一臺虛擬機的IP地址
$ curl http://192.168.0.10:10000/
It works!
接著扎阶,我們來測試一下這個 Nginx 服務的性能。在第二個終端運行下面的 ab 命令婶芭。要注意东臀,與上次操作不同的是,這次我們需要并發(fā) 100 個請求測試 Nginx 性能犀农,總共測試 1000 個請求啡邑。
# 并發(fā)100個請求測試Nginx性能,總共測試1000個請求
$ ab -c 100 -n 1000 http://192.168.0.10: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)
...
從 ab 的輸出結(jié)果我們可以看到井赌,Nginx 能承受的每秒平均請求數(shù),只有 87 多一點贵扰,是不是感覺它的性能有點差呀仇穗。那么,到底是哪里出了問題呢戚绕?我們再用 top 和 pidstat 來觀察一下纹坐。
這次,我們在第二個終端舞丛,將測試的并發(fā)請求數(shù)改成 5耘子,同時把請求時長設置為 10 分鐘(-t 600)。這樣球切,當你在第一個終端使用性能分析工具時谷誓, Nginx 的壓力還是繼續(xù)的。
繼續(xù)在第二個終端運行 ab 命令:
$ ab -c 5 -t 600 http://192.168.0.10:10000/
然后吨凑,我們在第一個終端運行 top 命令捍歪,觀察系統(tǒng)的 CPU 使用情況:
$ top
...
%Cpu(s): 80.8 us, 15.1 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 8456 5052 3884 S 2.7 0.1 0:04.78 docker-containe
6947 systemd+ 20 0 33104 3716 2340 S 2.7 0.0 0:04.92 nginx
7494 daemon 20 0 336696 15012 7332 S 2.0 0.2 0:03.55 php-fpm
7495 daemon 20 0 336696 15160 7480 S 2.0 0.2 0:03.55 php-fpm
10547 daemon 20 0 336696 16200 8520 S 2.0 0.2 0:03.13 php-fpm
10155 daemon 20 0 336696 16200 8520 S 1.7 0.2 0:03.12 php-fpm
10552 daemon 20 0 336696 16200 8520 S 1.7 0.2 0:03.12 php-fpm
15006 root 20 0 1168608 66264 37536 S 1.0 0.8 9:39.51 dockerd
4323 root 20 0 0 0 0 I 0.3 0.0 0:00.87 kworker/u4:1
...
觀察 top 輸出的進程列表可以發(fā)現(xiàn),CPU 使用率最高的進程也只不過才 2.7%鸵钝,看起來并不高糙臼。
然而,再看系統(tǒng) CPU 使用率( %Cpu )這一行恩商,你會發(fā)現(xiàn)变逃,系統(tǒng)的整體 CPU 使用率是比較高的:用戶 CPU 使用率(us)已經(jīng)到了 80%,系統(tǒng) CPU 為 15.1%怠堪,而空閑 CPU (id)則只有 2.8%揽乱。
為什么用戶 CPU 使用率這么高呢名眉?我們再重新分析一下進程列表,看看有沒有可疑進程:
docker-containerd 進程是用來運行容器的锤窑,2.7% 的 CPU 使用率看起來正常璧针;
Nginx 和 php-fpm 是運行 Web 服務的,它們會占用一些 CPU 也不意外渊啰,并且 2% 的 CPU 使用率也不算高探橱;
再往下看,后面的進程呢绘证,只有 0.3% 的 CPU 使用率隧膏,看起來不太像會導致用戶 CPU 使用率達到 80%。
那就奇怪了嚷那,明明用戶 CPU 使用率都 80% 了胞枕,可我們挨個分析了一遍進程列表,還是找不到高 CPU 使用率的進程魏宽「海看來 top 是不管用了,那還有其他工具可以查看進程 CPU 使用情況嗎队询?不知道你記不記得我們的老朋友 pidstat派桩,它可以用來分析進程的 CPU 使用情況。
接下來蚌斩,我們還是在第一個終端铆惑,運行 pidstat 命令:
# 間隔1秒輸出一組數(shù)據(jù)(按Ctrl+C結(jié)束)
$ pidstat 1
...
04:36:24 UID PID %usr %system %guest %wait %CPU CPU Command
04:36:25 0 6882 1.00 3.00 0.00 0.00 4.00 0 docker-containe
04:36:25 101 6947 1.00 2.00 0.00 1.00 3.00 1 nginx
04:36:25 1 14834 1.00 1.00 0.00 1.00 2.00 0 php-fpm
04:36:25 1 14835 1.00 1.00 0.00 1.00 2.00 0 php-fpm
04:36:25 1 14845 0.00 2.00 0.00 2.00 2.00 1 php-fpm
04:36:25 1 14855 0.00 1.00 0.00 1.00 1.00 1 php-fpm
04:36:25 1 14857 1.00 2.00 0.00 1.00 3.00 0 php-fpm
04:36:25 0 15006 0.00 1.00 0.00 0.00 1.00 0 dockerd
04:36:25 0 15801 0.00 1.00 0.00 0.00 1.00 1 pidstat
04:36:25 1 17084 1.00 0.00 0.00 2.00 1.00 0 stress
04:36:25 0 31116 0.00 1.00 0.00 0.00 1.00 0 atopacctd
...
觀察一會兒,你是不是發(fā)現(xiàn)送膳,所有進程的 CPU 使用率也都不高啊员魏,最高的 Docker 和 Nginx 也只有 4% 和 3%,即使所有進程的 CPU 使用率都加起來叠聋,也不過是 21%撕阎,離 80% 還差得遠呢!
最早的時候晒奕,我碰到這種問題就完全懵了:明明用戶 CPU 使用率已經(jīng)高達 80%闻书,但我卻怎么都找不到是哪個進程的問題。到這里脑慧,你也可以想想魄眉,你是不是也遇到過這種情況?還能不能再做進一步的分析呢闷袒?
后來我發(fā)現(xiàn)坑律,會出現(xiàn)這種情況,很可能是因為前面的分析漏了一些關鍵信息。你可以先暫停一下晃择,自己往上翻冀值,重新操作檢查一遍」溃或者列疗,我們一起返回去分析 top 的輸出,看看能不能有新發(fā)現(xiàn)。
現(xiàn)在,我們回到第一個終端佩抹,重新運行 top 命令家凯,并觀察一會兒:
$ top
top - 04:58:24 up 14 days, 15:47, 1 user, load average: 3.39, 3.82, 2.74
Tasks: 149 total, 6 running, 93 sleeping, 0 stopped, 0 zombie
%Cpu(s): 77.7 us, 19.3 sy, 0.0 ni, 2.0 id, 0.0 wa, 0.0 hi, 1.0 si, 0.0 st
KiB Mem : 8169348 total, 2543916 free, 457976 used, 5167456 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 7363908 avail Mem
?
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
6947 systemd+ 20 0 33104 3764 2340 S 4.0 0.0 0:32.69 nginx
6882 root 20 0 12108 8360 3884 S 2.0 0.1 0:31.40 docker-containe
15465 daemon 20 0 336696 15256 7576 S 2.0 0.2 0:00.62 php-fpm
15466 daemon 20 0 336696 15196 7516 S 2.0 0.2 0:00.62 php-fpm
15489 daemon 20 0 336696 16200 8520 S 2.0 0.2 0:00.62 php-fpm
6948 systemd+ 20 0 33104 3764 2340 S 1.0 0.0 0:00.95 nginx
15006 root 20 0 1168608 65632 37536 S 1.0 0.8 9:51.09 dockerd
15476 daemon 20 0 336696 16200 8520 S 1.0 0.2 0:00.61 php-fpm
15477 daemon 20 0 336696 16200 8520 S 1.0 0.2 0:00.61 php-fpm
24340 daemon 20 0 8184 1616 536 R 1.0 0.0 0:00.01 stress
24342 daemon 20 0 8196 1580 492 R 1.0 0.0 0:00.01 stress
24344 daemon 20 0 8188 1056 492 R 1.0 0.0 0:00.01 stress
24347 daemon 20 0 8184 1356 540 R 1.0 0.0 0:00.01 stress
...
注意:如果觀察不到stress(進程太多 top不顯示所有進程) 請使用top -b -n 1 > ./top.log 然后cat top.log
這次從頭開始看 top 的每行輸出牙捉,咦?Tasks 這一行看起來有點奇怪,就緒隊列中居然有 6 個 Running 狀態(tài)的進程(6 running),是不是有點多呢产艾?
回想一下 ab 測試的參數(shù),并發(fā)請求數(shù)是 5滑绒。再看進程列表里闷堡, php-fpm 的數(shù)量也是 5,再加上 Nginx疑故,好像同時有 6 個進程也并不奇怪缚窿。但真的是這樣嗎?
再仔細看進程列表焰扳,這次主要看 Running(R) 狀態(tài)的進程。你有沒有發(fā)現(xiàn)误续, Nginx 和所有的 php-fpm 都處于 Sleep(S)狀態(tài)吨悍,而真正處于 Running(R)狀態(tài)的,卻是幾個 stress 進程蹋嵌。這幾個 stress 進程就比較奇怪了育瓜,需要我們做進一步的分析。
我們還是使用 pidstat 來分析這幾個進程栽烂,并且使用 -p 選項指定進程的 PID躏仇。首先,從上面 top 的結(jié)果中腺办,找到這幾個進程的 PID焰手。比如,先隨便找一個 24344怀喉,然后用 pidstat 命令看一下它的 CPU 使用情況:
$ pidstat -p 24344
?
16:14:55 UID PID %usr %system %guest %wait %CPU CPU Command
奇怪书妻,居然沒有任何輸出。難道是 pidstat 命令出問題了嗎躬拢?之前我說過躲履,在懷疑性能工具出問題前见间,最好還是先用其他工具交叉確認一下。那用什么工具呢工猜? ps 應該是最簡單易用的米诉。我們在終端里運行下面的命令,看看 24344 進程的狀態(tài):
# 從所有進程中查找PID是24344的進程
$ ps aux | grep 24344
root 9628 0.0 0.0 14856 1096 pts/0 S+ 16:15 0:00 grep --color=auto 24344
還是沒有輸出∨袼В現(xiàn)在終于發(fā)現(xiàn)問題史侣,原來這個進程已經(jīng)不存在了,所以 pidstat 就沒有任何輸出犹褒。既然進程都沒了抵窒,那性能問題應該也跟著沒了吧。我們再用 top 命令確認一下:
$ 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
...
好像又錯了叠骑。結(jié)果還跟原來一樣李皇,用戶 CPU 使用率還是高達 80.9%,系統(tǒng) CPU 接近 15%宙枷,而空閑 CPU 只有 2.8%掉房,Running 狀態(tài)的進程有 Nginx、stress 等慰丛。
可是卓囚,剛剛我們看到 stress 進程不存在了,怎么現(xiàn)在還在運行呢诅病?再細看一下 top 的輸出哪亿,原來,這次 stress 進程的 PID 跟前面不一樣了贤笆,原來的 PID 24344 不見了蝇棉,現(xiàn)在的是 6779。
進程的 PID 在變芥永,這說明什么呢篡殷?在我看來,要么是這些進程在不停地重啟埋涧,要么就是全新的進程板辽,這無非也就兩個原因:
第一個原因,進程在不停地崩潰重啟棘催,比如因為段錯誤劲弦、配置錯誤等等,這時醇坝,進程在退出后可能又被監(jiān)控系統(tǒng)自動重啟了瓶您。
第二個原因,這些進程都是短時進程,也就是在其他應用內(nèi)部通過 exec 調(diào)用的外面命令呀袱。這些命令一般都只運行很短的時間就會結(jié)束贸毕,你很難用 top 這種間隔時間比較長的工具發(fā)現(xiàn)(上面的案例,我們碰巧發(fā)現(xiàn)了)夜赵。
至于 stress明棍,我們前面提到過,它是一個常用的壓力測試工具寇僧。它的 PID 在不斷變化中摊腋,看起來像是被其他進程調(diào)用的短時進程。要想繼續(xù)分析下去嘁傀,還得找到它們的父進程兴蒸。
要怎么查找一個進程的父進程呢?沒錯细办,用 pstree(yum -y install psmisc
) 就可以用樹狀形式顯示所有進程之間的關系:
$ pstree | grep stress
|-docker-containe-+-php-fpm-+-php-fpm---sh---stress
| |-3*[php-fpm---sh---stress---stress]
從這里可以看到橙凳,stress 是被 php-fpm 調(diào)用的子進程,并且進程數(shù)量不止一個(這里是 3 個)笑撞。找到父進程后岛啸,我們能進入 app 的內(nèi)部分析了。
首先茴肥,當然應該去看看它的源碼坚踩。運行下面的命令,把案例應用的源碼拷貝到 app 目錄瓤狐,然后再執(zhí)行 grep 查找是不是有代碼再調(diào)用 stress 命令:
# 拷貝源碼到本地
$ docker cp phpfpm:/app .
# grep 查找看看是不是有代碼在調(diào)用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 文件中直接調(diào)用了 stress 命令。
再來看看 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!";
}
?>
可以看到础锐,源碼里對每個請求都會調(diào)用一個 stress 命令赴捞,模擬 I/O 壓力。從注釋上看郁稍,stress 會通過 write() 和 unlink() 對 I/O 進程進行壓測,看來胜宇,這應該就是系統(tǒng) CPU 使用率升高的根源了耀怜。
不過,stress 模擬的是 I/O 壓力桐愉,而之前在 top 的輸出中看到的财破,卻一直是用戶 CPU 和系統(tǒng) CPU 升高,并沒見到 iowait 升高从诲。這又是怎么回事呢左痢?stress 到底是不是 CPU 使用率升高的原因呢?
我們還得繼續(xù)往下走。從代碼中可以看到俊性,給請求加入 verbose=1 參數(shù)后略步,就可以查看 stress 的輸出。你先試試看定页,在第二個終端運行:
$ curl http://192.168.0.10:10000?verbose=1
Server internal error: Array
(
[0] => stress: info: [19607] dispatching hogs: 0 cpu, 0 io, 0 vm, 1 hdd
[1] => stress: FAIL: [19608] (563) mkstemp failed: Permission denied
[2] => stress: FAIL: [19607] (394) <-- worker 19608 returned error 1
[3] => stress: WARN: [19607] (396) now reaping child worker processes
[4] => stress: FAIL: [19607] (400) kill error: No such process
[5] => stress: FAIL: [19607] (451) failed run completed in 0s
)
看錯誤消息 mkstemp failed: Permission denied 趟薄,以及 failed run completed in 0s。原來 stress 命令并沒有成功典徊,它因為權(quán)限問題失敗退出了杭煎。看來卒落,我們發(fā)現(xiàn)了一個 PHP 調(diào)用外部 stress 命令的 bug:沒有權(quán)限創(chuàng)建臨時文件羡铲。
從這里我們可以猜測,正是由于權(quán)限錯誤儡毕,大量的 stress 進程在啟動時初始化失敗也切,進而導致用戶 CPU 使用率的升高。
分析出問題來源妥曲,下一步是不是就要開始優(yōu)化了呢贾费?當然不是!既然只是猜測檐盟,那就需要再確認一下褂萧,這個猜測到底對不對,是不是真的有大量的 stress 進程葵萎。該用什么工具或指標呢导犹?
我們前面已經(jīng)用了 top、pidstat羡忘、pstree 等工具谎痢,沒有發(fā)現(xiàn)大量的 stress 進程。那么卷雕,還有什么其他的工具可以用嗎节猿?
還記得上一期提到的 perf 嗎?它可以用來分析 CPU 性能事件漫雕,用在這里就很合適滨嘱。依舊在第一個終端中運行 perf record -g 命令 ,并等待一會兒(比如 15 秒)后按 Ctrl+C 退出浸间。然后再運行 perf report 查看報告:
# 記錄性能事件太雨,等待大約15秒后按 Ctrl+C 退出
$ perf record -g
$ find | grep perf.data
$ 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
這樣,你就可以看到下圖這個性能報告:
你看魁蒜,stress 占了所有 CPU 時鐘事件的 77%囊扳,而 stress 調(diào)用調(diào)用棧中比例最高的吩翻,是隨機數(shù)生成函數(shù) random(),看來它的確就是 CPU 使用率升高的元兇了锥咸。隨后的優(yōu)化就很簡單了狭瞎,只要修復權(quán)限問題,并減少或刪除 stress 的調(diào)用她君,就可以減輕系統(tǒng)的 CPU 壓力脚作。
當然,實際生產(chǎn)環(huán)境中的問題一般都要比這個案例復雜缔刹,在你找到觸發(fā)瓶頸的命令行后球涛,卻可能發(fā)現(xiàn),這個外部命令的調(diào)用過程是應用核心邏輯的一部分校镐,并不能輕易減少或者刪除亿扁。
這時,你就得繼續(xù)排查鸟廓,為什么被調(diào)用的命令从祝,會導致 CPU 使用率升高或 I/O 升高等問題。這些復雜場景的案例引谜,我會在后面的綜合實戰(zhàn)里詳細分析牍陌。
最后,在案例結(jié)束時员咽,不要忘了清理環(huán)境毒涧,執(zhí)行下面的 Docker 命令,停止案例中用到的 Nginx 進程:
$ docker rm -f nginx phpfpm
execsnoop
在這個案例中贝室,我們使用了 top契讲、pidstat、pstree 等工具分析了系統(tǒng) CPU 使用率高的問題滑频,并發(fā)現(xiàn) CPU 升高是短時進程 stress 導致的捡偏,但是整個分析過程還是比較復雜的。對于這類問題峡迷,有沒有更好的方法監(jiān)控呢银伟?
execsnoop 就是一個專為短時進程設計的工具。它通過 ftrace 實時監(jiān)控進程的 exec() 行為绘搞,并輸出短時進程的基本信息彤避,包括進程 PID、父進程 PID看杭、命令行參數(shù)以及執(zhí)行的結(jié)果。比如挟伙,用 execsnoop 監(jiān)控上述案例楼雹,就可以直接得到 stress 進程的父進程 PID 以及它的命令行參數(shù)模孩,并可以發(fā)現(xiàn)大量的 stress 進程在不停啟動:
# 按 Ctrl+C 結(jié)束
$ execsnoop
PCOMM PID PPID RET ARGS
sh 30394 30393 0
stress 30396 30394 0 /usr/local/bin/stress -t 1 -d 1
sh 30398 30393 0
stress 30399 30398 0 /usr/local/bin/stress -t 1 -d 1
sh 30402 30400 0
stress 30403 30402 0 /usr/local/bin/stress -t 1 -d 1
sh 30405 30393 0
stress 30407 30405 0 /usr/local/bin/stress -t 1 -d 1
...
execsnoop 所用的 ftrace 是一種常用的動態(tài)追蹤技術,一般用于分析 Linux 內(nèi)核的運行時行為贮缅,后面課程我也會詳細介紹并帶你使用榨咐。小結(jié)
小結(jié)
碰到常規(guī)問題無法解釋的 CPU 使用率情況時,首先要想到有可能是短時應用導致的問題谴供,比如有可能是下面這兩種情況块茁。
第一,應用里直接調(diào)用了其他二進制程序桂肌,這些程序通常運行時間比較短数焊,通過 top 等工具也不容易發(fā)現(xiàn)。
第二崎场,應用本身在不停地崩潰重啟佩耳,而啟動過程的資源初始化,很可能會占用相當多的 CPU谭跨。
對于這類進程干厚,我們可以用 pstree 或者 execsnoop 找到它們的父進程,再從父進程所在的應用入手螃宙,排查問題的根源蛮瞄。
歡迎關注微信公眾號:軟件測試汪。軟件測試交流群:809111560
轉(zhuǎn)載請注意出處谆扎,謝謝合作