
最近接到一個需求,産品說要對一個接口做負載均衡。當時我聽到這個需求的時候,我的内心是奔潰的——這接口隻有一個,怎麼做負載均衡,負載均衡起碼得有兩個才能做啊!
最後了解了産品想要做的東西:由于線上某接口請求量過大,導緻程式當機,他想要做的是擴大這個接口的健壯性。通俗點說就是不要讓程式挂掉,就可以了。
在做這個需求的時候,我首先簡單對這個接口進行了簡單的性能測試,在此記錄。
性能測試工具
- Jmeter
- JProfile
測試名額介紹
- 響應時間(RT, Response Time):用戶端從發起請求到接收最後一個位元組資料為止所消耗的時間。
- 每秒查詢數(QPS, Queries Per Second):伺服器在一秒内處理的請求次數。
- 吞吐量(throughput):機關時間内系統處理使用者的請求數
- 其他…
Jmeter配置
對于此次接口性能測試,我在
Jmeter
中添加的所有元件及處理器如下
所有元件及處理器
- 線程組:發起請求的線程數,循環次數等參數
- HTTP請求:請求的協定、伺服器、端口、請求位址、請求參數等
- 結果樹:記錄了請求的響應資訊
- 響應時間圖:以圖表的形式反應請求的響應時間
- 彙總報告:自動統計本次測試資料,包括樣本數、平均響應時間、最大最小響應時間、異常率、吞吐量、資料包接收等
- 生成概要結果:主要用于統計請求總時間,其他名額與彙總報告有重疊,不再贅述
單線程請求的性能測試
首先測試的是接口的平均響應時間,我線上程組中配置了一個線程,循環100次。
ramp-up period
參數的作用是在此時間内建立全部的線程,這裡不需要改動。
線程組配置
關于響應時間圖的配置,首先需要設定一個輸出檔案路徑,然後配置合适的時間間隔(不同的時間間隔顯示的圖表會不一緻),我這裡配置的是10毫秒。
響應時間圖配置
結果樹在響應時間的測試中并不重要,彙總報告和概要結果不需要配置。
在完成了上述的配置之後,點選啟動按鈕,在等待一段時間後,整個測試流程結束,首先打開響應時間圖中的 顯示圖表 。
響應時間圖
從上面的圖形中可以粗略看到,每次請求的平均響應時間大概在40ms左右。
同時,可以在 彙總報告 界面看到本次測試的資料結果。
彙總報告
從表格中可以看到,總共的樣本數是100,平均響應時間為41ms,最小響應時間為28ms,最大響應時間為135毫秒,請求出錯的機率是0.00%,吞吐量是每秒23.7次,資料包的統計值暫且不論。
由于本次測試是由一個線程順序執行完成的,我麼可以得出一個結論:在同一時間内隻有一個使用者對該接口發起請求時,該接口的平均響應時間為41ms。
以上對于單個使用者請求的性能測試隻是相當于一個試用
Jmeter
的
demo
工程,因為在正常情況下,線上系統的使用者不可能隻有一個,是以以上得出的結論不能代表這個接口的性能,我們需要找到一個合适的最佳并發數,然後進行并發測試。
并發請求的性能測試
将線程組中循環次數的配置項改為10次(為了縮短測試時間),然後通過改變線程數進行多次測試,得到的測試結果如下表。
線程數 | 樣本數 | 請求總時間(ms) | 平均響應時間RT(ms) | 吞吐量ThoughPut(個/s) | QPS(個/s) |
1 | 10 | 1 | 60 | 16.6 | 10 |
10 | 100 | 2 | 145 | 64.5 | 50 |
20 | 200 | 3 | 270 | 67.7 | 66.7 |
30 | 300 | 4 | 349 | 79.4 | 75 |
40 | 400 | 6 | 511 | 68.7 | 66.7 |
50 | 500 | 8 | 735 | 64.4 | 62.5 |
60 | 600 | 11 | 970 | 57.6 | 54.5 |
QPS = 樣本數/請求總時間,此接口為查詢接口,故QPS與TPS可視為相同。
可以看到,當線程數為60個線程時,吞吐量和QPS都開始小于線程數,說明此時已經是一個瓶頸了,如果再往上加并發數,性能會越來越低,是以本接口的 最佳并發數 是50左右。
同時,觀察到吞吐量呈一個先上升後下降的趨勢,最高點即為 最大吞吐量 是79.4/s。
最後來測試 最大并發數 ,繼續增加線程數,當程式開始抛出
Error
異常,同時 彙總報告 中錯誤率不再為0%時,就達到了最大并發數,通過漫長的僞二分測試,我得到了本程式的最大并發數為160。
基于 Jmeter 的性能測試到這裡就結束了,主要涉及的名額有平均響應時間(RT)、吞吐量(Thoughput)、每秒查詢數(QPS)、最佳并發數、最大吞吐量、最大并發數。
回到最初的需求——排查當機原因——其實在日志裡面說的很清楚了,是由于堆記憶體溢出。
而在上述的壓測中,本程式的最大并發數隻有160的原因是它的堆大小初始值隻有256MB,使用
-Xms512m
啟動附加指令将初始堆大小擴大為512MB,最大并發數也随之擴大,在相同的情況下就不會再出現堆記憶體溢出的情況了,後續就算并發數再擴大一倍也不會再出現當機的情況(除非服務消費端循環調個幾千次,并發數又增加好幾倍…)。
再小結一次
在寫完這篇性能測試小記之後,又有些新的内容做下分享:
首先是在測試之前,需要知道線上JVM、伺服器的各種配置,本地程式的環境盡可能地模拟線上環境。
第二是并發數,最好是線上環境有PV的統計,這樣就可以知道在當機時系統的通路量,在
Jmeter
的線程數的配置時直接填通路量就可以,這樣做的目标最終其實也是模拟線上的真實環境。
第三是考慮從代碼上進行優化,比如說配置檔案中的配置項可以解析為配置類在程式啟動時就加載進來,而不是每次使用到的時候就去解析一次配置檔案,這樣做毫無意義(我也不知道項目裡面為什麼這麼寫,過幾天把它優化掉)。