效能分析(2)- 應用程式 CPU 使用率過高案例

小菠蘿測試筆記發表於2020-07-30

效能分析小案例系列,可以通過下面連結檢視哦

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鍵可以展開

結果分析

最終是關係到 sqrtadd_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 好多了

 

相關文章