效能分析小案例系列,可以通過下面連結檢視哦
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
按方向鍵可上下切換,有+的按Enter鍵可以展開
結果分析
最終是關係到 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 好多了