1. 程式人生 > >後臺性能測試不可不知的二三事

後臺性能測試不可不知的二三事

報告 空間 bold 返回 定義 需求 加鎖 交互 posit

某月黑風高之夜,某打車平臺上線了一大波(G+)優惠活動,眾人紛紛下單。於是乎,該打車平臺使用的智能提示服務扛不住直接趴窩了(如下圖)。事後,負責智能提示服務開發和運維的有關部門開會後決定:必須對智能提示服務進行一次全面深入的性能摸底,立刻!現在!馬上! 那麽一大坨問題就迎面而來:對於智能提示這樣的後臺服務,性能測試過程中應該關心那些指標?這些指標代表什麽含義?這些指標的通過標準是什麽?下面將為您一一解答。 概述 不同人群關註的性能指標各有側重。後臺服務接口的調用者一般只關心吞吐量、響應時間等外部指標。後臺服務的所有者不僅僅關註外部指標,還會關註CPU、內存、負載等內部指標。 拿某打車平臺來說,它所關心的是智能提示的外部指標能不能抗住因大波優惠所導致的流量激增。而對於智能提示服務的開發、運維、測試人員,不僅僅關註外部指標,還會關註CPU、內存、IO等內部指標,以及部署方式、服務器軟硬件配置等運維相關事項。
外部指標 從外部看,性能測試主要關註如下三個指標
  • 吞吐量:每秒鐘系統能夠處理的請求數、任務數。
  • 響應時間:服務處理一個請求或一個任務的耗時。
  • 錯誤率:一批請求中結果出錯的請求所占比例。
響應時間的指標取決於具體的服務。如智能提示一類的服務,返回的數據有效周期短(用戶多輸入一個字母就需要重新請求),對實時性要求比較高,響應時間的上限一般在100ms以內。而導航一類的服務,由於返回結果的使用周期比較長(整個導航過程中),響應時間的上限一般在2-5s。 對於響應時間的統計,應從均值、.90、.99、分布等多個角度統計,而不僅僅是給出均值。下圖是響應時間統計的一個例子 吞吐量的指標受到響應時間、服務器軟硬件配置、網絡狀態等多方面因素影響。
  • 吞吐量越大,響應時間越長。
  • 服務器硬件配置越高,吞吐量越大。
  • 網絡越差,吞吐量越小。
在低吞吐量下的響應時間的均值、分布比較穩定,不會產生太大的波動。 在高吞吐量下,響應時間會隨著吞吐量的增長而增長,增長的趨勢可能是線性的,也可能接近指數的。當吞吐量接近系統的峰值時,響應時間會出現激增。 錯誤率和服務的具體實現有關。通常情況下,由於網絡超時等外部原因造成的錯誤比例不應超過5%%,由於服務本身導致的錯誤率不應超過1% 。 內部指標 從服務器的角度看,性能測試主要關註CPU、內存、服務器負載、網絡、磁盤IO等 CPU 後臺服務的所有指令和數據處理都是由CPU負責,服務對CPU的利用率對服務的性能起著決定性的作用。 Linux系統的CPU主要有如下幾個維度的統計數據
  • us:用戶態使用的cpu時間百分比
  • sy:系統態使用的cpu時間百分比
  • ni:用做nice加權的進程分配的用戶態cpu時間百分比
  • id:空閑的cpu時間百分比
  • wa:cpu等待IO完成時間百分比
  • hi:硬中斷消耗時間百分比
  • si:軟中斷消耗時間百分比
下圖是線上開放平臺轉發服務某臺服務器上top命令的輸出,下面以這個服務為例對CPU各項指標進行說明 us & sy:大部分後臺服務使用的CPU時間片中us和sy的占用比例是最高的。同時這兩個指標又是互相影響的,us的比例高了,sy的比例就低,反之亦然。通常sy比例過高意味著被測服務在用戶態和系統態之間切換比較頻繁,此時系統整體性能會有一定下降。另外,在使用多核CPU的服務器上,CPU 0負責CPU各核間的調度,CPU 0上的使用率過高會導致其他CPU核心之間的調度效率變低。因此測試過程中CPU 0需要重點關註。 ni:每個Linux進程都有個優先級,優先級高的進程有優先執行的權利,這個叫做pri。進程除了優先級外,還有個優先級的修正值。這個修正值就叫做進程的nice值。一般來說,被測服務和服務器整體的ni值不會很高。如果測試過程中ni的值比較高,需要從服務器Linux系統配置、被測服務運行參數查找原因 id:線上服務運行過程中,需要保留一定的id冗余來應對突發的流量激增。在性能測試過程中,如果id一直很低,吞吐量上不去,需要檢查被測服務線程/進程配置、服務器系統配置等。 wa:磁盤、網絡等IO操作會導致CPU的wa指標提高。通常情況下,網絡IO占用的wa資源不會很高,而頻繁的磁盤讀寫會導致wa激增。如果被測服務不是IO密集型的服務,那需要檢查被測服務的日誌量、數據載入頻率等。 hi & si:硬中斷是外設對CPU的中斷,即外圍硬件發給CPU或者內存的異步信號就是硬中斷信號;軟中斷由軟件本身發給操作系統內核的中斷信號。通常是由硬中斷處理程序或進程調度程序對操作系統內核的中斷,也就是我們常說的系統調用(System Call)。在性能測試過程中,hi會有一定的CPU占用率,但不會太高。對於IO密集型的服務,si的CPU占用率會高一些。 內存 性能測試過程中對內存監控的主要目的是檢查被測服務所占用內存的波動情況。 在Linux系統中有多個命令可以獲取指定進程的內存使用情況,最常用的是top命令,如下圖所示 其中
  • VIRT:進程所使用的虛擬內存的總數。它包括所有的代碼,數據和共享庫,加上已換出的頁面,所有已申請的總內存空間
  • RES:進程正在使用的沒有交換的物理內存(棧、堆),申請內存後該內存段已被重新賦值
  • SHR:進程使用共享內存的總數。該數值只是反映可能與其它進程共享的內存,不代表這段內存當前正被其他進程使用
  • SWAP:進程使用的虛擬內存中被換出的大小,交換的是已經申請,但沒有使用的空間,包括(棧、堆、共享內存)
  • DATA:進程除可執行代碼以外的物理內存總量,即進程棧、堆申請的總空間
從上面的解釋可以看出,測試過程中主要監控RES和VIRT,對於使用了共享內存的多進程架構服務,還需要監沙發控SHR。 LOAD(服務器負載) Linux的系統負載指運行隊列的平均長度,也就是等待CPU的平均進程數 從服務器負載的定義可以看出,服務器運行最理想的狀態是所有CPU核心的運行隊列都為1,即所有活動進程都在運行,沒有等待。這種狀態下服務器運行在負載閾值下。 通常情況下,按照經驗值,服務器的負載應位於閾值的70%~80%,這樣既能利用服務器大部分性能,又留有一定的性能冗余應對流量增長。 Linux提供了很多查看系統負載的命令,最常用的是top和uptime top和uptime針對負載的輸出內容相同,都是系統最近1分鐘、5分鐘、15分鐘的負載均值 查看系統負載閾值的命令如下 在性能測試過程中,系統負載是評價整個系統運行狀況最重要的指標之一。通常情況下,壓力測試時系統負載應接近但不能超過閾值,並發測試時的系統負載最高不能超過閾值的80%,穩定性測試時,系統負載應在閾值的50%左右。 網絡 性能測試中網絡監控主要包括網絡流量、網絡連接狀態的監控。 網絡流量監控 可以使用nethogs命令。該命令與top類似,是一個實時交互的命令,運行界面如下 在後臺服務性能測試中,對於返回文本結果的服務,並不需要太多關註在流量方面。 網絡連接狀態監控 性能測試中對網絡的監控主要是監控網絡連接狀態的變化和異常。對於使用TCP協議的服務,需要監控服務已建立連接的變化情況(即ESTABLISHED狀態的TCP連接)。對於HTTP協議的服務,需要監控被測服務對應進程的網絡緩沖區的狀態、TIME_WAIT狀態的連接數等。Linux自帶的很多命令如netstat、ss都支持如上功能。下圖是netstat對指定pid進程的監控結果 磁盤IO 性能測試過程中,如果被測服務對磁盤讀寫過於頻繁,會導致大量請求處於IO等待的狀態,系統負載升高,響應時間變長,吞吐量下降。 Linux下可以用iostat命令來監控磁盤狀態,如下圖
  • tps:該設備每秒的傳輸次數。“一次傳輸”意思是“一次I/O請求”。多個邏輯請求可能會被合並為“一次I/O請求”。“一次傳輸”請求的大小是未知的
  • kB_read/s:每秒從設備(driveexpressed)讀取的數據量,單位為Kilobytes
  • kB_wrtn/s:每秒向設備(driveexpressed)寫入的數據量,單位為Kilobytes
  • kB_read:讀取的總數據量,單位為Kilobytes
  • kB_wrtn:寫入的總數量數據量,單位為Kilobytes
從iostat的輸出中,能夠獲得系統運行最基本的統計數據。但對於性能測試來說,這些數據不能提供更多的信息。需要加上-x參數
  • rrqm/s:每秒這個設備相關的讀取請求有多少被Merge了(當系統調用需要讀取數據的時候,VFS將請求發到各個FS,如果FS發現不同的讀取請求讀取的是相同Block的數據,FS會將這個請求合並Merge)
  • wrqm/s:每秒這個設備相關的寫入請求有多少被Merge了
  • await:每一個IO請求的處理的平均時間(單位是毫秒)
  • %util:在統計時間內所有處理IO時間,除以總共統計時間。例如,如果統計間隔1秒,該設備有0.8秒在處理IO,而0.2秒閑置,那麽該設備的%util = 0.8/1 = 80%,該參數暗示了設備的繁忙程度。
常見性能瓶頸
  • 吞吐量到上限時系統負載未到閾值:一般是被測服務分配的系統資源過少導致的。測試過程中如果發現此類情況,可以從ulimit、系統開啟的線程數、分配的內存等維度定位問題原因
  • CPU的us和sy不高,但wa很高:如果被測服務是磁盤IO密集型型服務,wa高屬於正常現象。但如果不是此類服務,最可能導致wa高的原因有兩個,一是服務對磁盤讀寫的業務邏輯有問題,讀寫頻率過高,寫入數據量過大,如不合理的數據載入策略、log過多等,都有可能導致這種問題。二是服務器內存不足,服務在swap分區不停的換入換出。
  • 同一請求的響應時間忽大忽小:在正常吞吐量下發生此問題,可能的原因有兩方面,一是服務對資源的加鎖邏輯有問題,導致處理某些請求過程中花了大量的時間等待資源解鎖;二是Linux本身分配給服務的資源有限,某些請求需要等待其他請求釋放資源後才能繼續執行。
  • 內存持續上漲:在吞吐量固定的前提下,如果內存持續上漲,那麽很有可能是被測服務存在明顯的內存泄漏,需要使用valgrind等內存檢查工具進行定位。
舉個 (栗子) 例子 智能提示服務趴窩了以後,必須立刻對其做性能摸底。根據目前的情況,測試結果中需要提供外部指標和內部指標。 智能提示服務的架構和每個模塊的功能如下圖所示 從圖中我們可以看出,測試前智能提示服務的底層數據服務已經確定了性能上限。因此,本次測試我們的任務是在底層數據服務性能為3500qps的前提下,找到智能提示服務上遊各個模塊的性能上限。 一個完整的後臺服務性能測試流程如下圖所示。 測試前準備:
  • 測試數據:由於智能提示已經在線上運行,本次測試使用智能提示趴窩那天的日誌作為測試數據
  • QPS預估:本次測試就是為了找這個數
  • 服務器配置:使用與線上軟硬件配置相同的服務器
壓測過程: 我們使用Jmeter發送測試數據來模擬用戶請求,Jmeter測試配置文件使用的原件如下圖所示。從圖中可以看出,性能測試的配置文件主要由數據文件配置(線程間共享方式、到達末尾時的行為等)、吞吐量控制、HTTP采樣器(域名、端口、HTTP METHOD、請求body等)、響應斷言(對返回結果的內容進行校驗)。 數據文件配置 吞吐量控制 HTTP請求采樣 響應斷言
  • CPU
在linux中,sar、top、ps等命令都可以對cpu使用情況進行監控。一般來說,最常用的是top命令。top命令的輸出如下: top命令是一個交互式命令,運行後會一直保持在終端並定時刷新。在性能測試中,可以使用如下參數讓top命令只運行一次 $top –n 1 –b –p ${pid}
  • 服務器負載
linux中,服務器負載使用uptime命令獲取,該命令的輸出如下圖 每一列的含義如下: “當前時間 系統運行時長 登錄的用戶數最 近1分鐘、5分鐘、15分鐘的平均負載”
  • 內存
在linux中, top、ps命令都可以對指定進程的內存使用狀況進行查看。但最準確的信息在/proc/${PID}/status中,如下圖 上面命令的輸出中,我們重點關註VmRSS、VmData、VmSize
  • 磁盤IO
磁盤監控數據使用iostat命令獲取 測試報告輸出 在統計完性能測試過程中收集的監控指標後,就可以輸出性能報告了。 通常來說,性能報告中要包含如下內容:
  • 測試結論:包括被測服務最大QPS、響應時間等指標是否達到期望,部署建議等。
  • 測試環境描述:包括性能需求、測試用服務器配置、測試數據來源、測試方法等
  • 監控指標統計:響應時間統計、QPS、服務器指標統計、進程指標統計。建議最好用圖表來表示統計數據。
結語 測試完畢後,得出的結論是單臺智能提示服務的性能是300qps,線上整套智能提示服務的性能是1800qps;而月黑風高那天的流量大概是5000qps+,難怪智能提示趴窩,確實流量太大,遠超線上的吞吐容量。 最後,智能提示服務申請了服務器進行擴容,並對某打車平臺的流量進行了限制,既開源又節流,保證今後月黑風高之夜一眾約酒、約飯、約P之人的打車體驗,提高了各種約的成功率,可謂功德無量。

後臺性能測試不可不知的二三事