性能分析小案例系列,可以通過下面鏈接查看哦
https://www.cnblogs.com/poloyy/category/1814570.html
系統架構背景

- VM1:用作 Web 服務器,來模擬性能問題
- VM2:用作 Web 服務器的客戶端,來給 Web 服務增加壓力請求
- 使用兩台虛擬機(均是 Ubuntu 18.04)是為了相互隔離,避免交叉感染
VM2 運行 ab 命令,初步觀察 Nginx 性能
簡單介紹 ab 命令
- ab(apache bench)是一個常用的 HTTP 服務性能測試工具
- 可以向目標服務器並發發送請求
運行 ab 命令
並發 10 個請求測試 VM1 的 Nginx 性能,總共測試 100 個請求
ab -c 10 -n 10 http://172.20.72.58:10000/

從 ab 的輸出結果可以看到,Nginx 能承受的每秒平均請求數只有 14.73(這也太辣雞了吧)
那到底是哪里出了問題呢
接下來,我們將通過一系列的命令來觀察哪里出問題了
深入分析
VM2 長時間運行 ab 命令
並發 10 個請求測試 VM1 的 Nginx 性能,總共測試 10000 個請求
ab -c 10 -n 10000 http://172.20.72.58:10000/
VM1 終端運行 top 命令
輸入后,按1,查看每個 CPU 的使用率

結果分析
- 系統中有幾個 php-fpm 進程的 CPU 使用率加起來接近 200%
- 而每個 CPU 的用戶使用率(us)也已經超過了 96%,接近飽和
- 結論:正是用戶空間的 php-fpm 進程,導致 CPU 使用率驟升
分析 php-fpm 進程到底是因為哪個函數導致了 CPU 使用率升高
在 VM1 終端運行 perf 命令
perf record -g -p 84408
- record:錄制的意思
- -g:開啟調用關系分析
- -p:指定 php-fpm 的進程號84408
錄制約 30s 后,ctrl+c 終止進程,然后可以在當前目錄下看到 perf.data 文件

然后執行下面命令,分析報告(perf.data)
perf report
按方向鍵可上下切換,有+的按回車鍵可以展開

結果分析
最終是關系到 sqrt 和 add_function 這兩個函數
查看 Nginx 應用的源碼,找到問題根源
找到 sqrt 函數
grep sqrt -r app/

原來只有 sqrt 函數在 app/index.php 文件中調用了
找到 add_function 函數
grep add_function -r app/
會發現找不到,因為 add_function 是 PHP 內置函數
查看 index.php 源碼
<?php // test only. $x = 0.0001; for ($i = 0; $i <= 1000000; $i++) { $x += sqrt($x); } echo "It works!"
可以看到,這里有一個循環很多次的代碼段
解決方法
找到問題的根源,就可以快速解決了,刪除循環代碼塊
<?php echo "It works!"
perf 拓展
其實有一條命令更方便查看函數
perf top -g -p 84408

那為啥我要用 perf record 然后再用 perf report 呢
因為如果沒有 perf 源碼的話,是無法讀取到 php 的函數,只會顯示一堆十六進制碼
修復問題后,驗證 Nginx 性能是否有所變化
VM2 終端再次運行 ab 命令
ab -c 10 -n 10000 http://172.20.72.58:10000/

結果分析
每秒請求數突飛猛進的升到 2500,比之前的 14 好多了
分析整體思路
- 使用 ab 短時間壓測,發現服務器性能低下,TPS 比較低
- 使用 ab 長時間壓測,讓服務器保持一個高負載的狀態,方便排查問題
- 通過 top 命令監控系統資源情況,發現用戶態的 CPU 使用率(us)很高,且進程列表中發現幾個進程的 CPU 使用率特別高,都是同一個 php 進程
- 通過 perf record 命令錄制進程一段時間
- 通過 perf report 查看錄制進程的結果數據,可以分析 php-fpm 進程到底是哪個函數導致 CPU 使用率高
- 找到 add_function、sqrt 函數
- 通過 grep 命令確認函數是在 index.php 代碼文件中
- 查看 index.php 文件的源碼,確認問題代碼塊
- 刪除問題代碼塊,重新壓測,每秒平均請求數有了質的飛升,成功解決問題
