有機會做了一次
性能測試工作,主要是預研性質的工作。開發人員有必要再提交給測試做性能測試之前,做一次比較粗糙的性能測試工作。
1)走通性能測試流程,從造數據到測試,可以走通,方可交由測試同學。畢竟開發(相對性能測試人員而非功能測試)對業務邏輯更了解一些。
2)測試一些顯而易見的bug;
3)建立性能方面的信心;
4)可在測試的同學做完測試以后做一個對比,不至于偏離太過離譜。
參照測試部門的意見,我把這次的性能測試總結了如下幾個步驟:
1、測試目標和范圍:根據需要滿足的非功能需求,確定上線功能點哪些需要測試。測試性能、穩定性、最大壓力。
2、測試方案準備:包括施壓方式,環境配置,環境依賴,資源監控,整理方案文檔。
3、環境準備:準備壓力測試環境,一般是壓力測試機配置,壓力測試數據庫配置。
4、數據準備:根據線上預估數據,對數據庫數據進行準備和模擬。
5、測試準備:包括需要編寫的程序,如其他系統間依賴可寫mock程序。另外編寫jmeter的測試計劃等。嘗試測試,并確保一個請求或處理過程能順利通過。
6、進行測試:通過客戶端施壓服務器,監控器各方面資源利用。
7、進行測試分析總結:寫測試報告。TPS,吞吐量,CPU占比等。對異?,F象記錄,如內存溢出等。
8、根據測試報告對程序進行優化或重構。
做技術還是有做技術的天性,我們開發最關心的也就是5-8的步驟。我們的應用主要以hessian接口的形式向外面暴露,另外的就是任務在后臺處理接口推送過來的數據。所以,我們的測試主要集中在接口測試和任務測試。比一般網頁的性能測試更簡單一些。
我們選用的施壓客戶端是開源的jmeter,文檔較為豐富,且操作極為方便,擴展性好。服務器端性能監控工具,均采用linux的shell命令和jvm自帶的工具或命令。jvm的工具已經夠強大了,測試團隊也是利用linux的命令采集服務器端資源,然后把消息發送到自己編寫的一些資源監控工具上,其實都是利用了原生的shell命令和jvm命令來周期性采集并繪圖的。
JMeter沒有現成的sampler施壓hessian的接口,所以我們需要利用它極具擴展性的java請 求sampler來施壓hessian接口。我們查看jmeter安裝目錄下的lib>ext下可以發現其他多種類型的sampler。其他的種類 都可以由javasampler來實現。我們只需要繼承org.apache.jmeter.protocol.java.sampler. AbstractJavaSamplerClient該類,在runTest方法中調用hessian接口,并封裝返回值即可。然后把工程打成jar包, 放到jmeter安裝目錄下的lib>ext下。啟動jemter,在利用javasampler就可以定為到我們編寫的擴展測試程序了。
在壓力測試過程中,包括兩部分的資源檢測,jvm的資源占用。一般利用jdk自帶工具集
1、jps
常用的幾個參數:
-l輸出java應用程序的mainclass的完整包
-q僅顯示pid,不顯示其它任何相關信息
-m輸出傳遞給main方法的參數
-v輸出傳遞給JVM的參數。在診斷JVM相關問題的時候,這個參數可以查看JVM相關參數的設置
2、jstat-JavaVirtualMachineStatisticsMonitoringTool
jstat[Options]vmid[interval][count]
Options--選項,我們一般使用-gcutil查看gc情況還有其他選項如:
-class-compiler-gc-gccapacity-gccause-gcnew-gcnewcapacity-gcold-gcoldcapacity-gcpermcapacity-gcutil-printcompilation
vmid--VM的進程號,即當前運行的java進程號
interval--間隔時間,單位為毫秒
count--打印次數,如果缺省則打印無數次
-----------------------------------------------jstat-gcutil[pid]輸出解釋
S0--Heap上的Survivorspace0區已使用空間的百分比
S1--Heap上的Survivorspace1區已使用空間的百分比
E--Heap上的Edenspace區已使用空間的百分比
O--Heap上的Oldspace區已使用空間的百分比
P--Permspace區已使用空間的百分比
YGC--從應用程序啟動到采樣時發生YoungGC的次數
YGCT--從應用程序啟動到采樣時YoungGC所用的時間(單位秒)
FGC--從應用程序啟動到采樣時發生FullGC的次數
FGCT--從應用程序啟動到采樣時FullGC所用的時間(單位秒)
GCT--從應用程序啟動到采樣時用于垃圾回收的總時間(單位秒)

3、jhat-JavaHeapAnalysisTool用于內存快照文件的分析,當然還有很多類似工具
4、jstatd-VirtualMachinejstatDaemon
5、jinfo-ConfigurationInfo
6、jvisualvm-JavaVirtualMachineMonitoring,Troubleshooting,andProfilingTool
7、jconsole-JavaMonitoringandManagementConsole
8、jmap-MemoryMapjvm內存分析工具,得到最普遍的使用。
jmap-histo<pid>b。log輸出內存類占用,對比各時段的內存類,可方便知道回收情況和占用情況。
jmap-dump:format=b,file=heap。dump<pid>輸出內存快照,可用許多開源工具分析內存快照。
jprofile太耗內存,如果靜態分析能得出結論的可避免使用
9、jstack-StackTrace打印線程的堆棧跟蹤信息
10、btrace-sun提供的檢測工具,很好很強大,用于檢測函數耗時等,微浸入。
而服務器端的資源監控多用Linux的shell命令如:top,free,vmstat,iostat,uptime等,詳細用法不累述。
本次測試過程中遇到的幾個誤區和犯的錯誤:
1、jmeter關于線程組的線程數和ramp-up值的設置,如果設置ramp-up為1秒,線程數為10,我錯誤的理解為這就是一秒內的請求量。其實是jmeter一秒內啟動了10個線程,這10個線程分別發送請求,知道服務器端返回后,再次發送。
這個錯誤的理解直接導致我們的一個異步接口(接口把數據保存在一個無上限queue中,另外起線程來消費)在壓力測試過程中,被壓垮,以為是內存泄露問題,其實只是我們的服務器沒能力處理這樣一個數據量。
2、在一個日志處理模塊中的生產和消費者模型中,產生的線程過多。后經過配置修改了消費者和生產者的比例。但是在定位問題時,產生很多困難,因為不知道是什么線程出現這么多。程序中所有的線程必須命名才方便工具的觀察,需要開發中規范和定義好。
3、對于任務類型的性能測試沒有返回值,我們怎么觀察任務處理一條記錄的時間,或單位時間內處理記錄的條數呢?開發 人員習慣在源代碼中去修改,并做trace,更好的方法是采用btrace工具來跟蹤方法的進出。它在監控方法的耗時,查看某些方法的參數值,監控內存使 用情況等一系列場合中使用。
4、開發錯誤的理解org。springframework。scheduling。concurrent。 ThreadPoolTaskExecutor類的corePoolSize和maxPoolSize和queueCapacity三者的關系。原以為 corePoolSize是啟動時變初始化的核心線程數,如果還有任務需要執行,那么就會新建線程到線程池中,直到達到最大maxPoolSize的大 小。然后放不下的任務才浸入queueCapacity中存儲。而實際情況確是:任務到達corePoolSize之后,就放入 queueCapacity的queue中了。造成我們的配置錯誤,引起串行的任務執行。
的確在開發功能測試中沒有發現的問題,通過性能測試暴露了出來。除了這些bug之外,我們還確認了我們接口的性能,任務的性能和穩定性。