性能測試到底該怎麼做?

  • 2021 年 7 月 23 日
  • 筆記

三高人群

作為一名開發者,我們最長聽到的就是編程界的三高:

高性能、高並發、高可用。

聽起來非常高大上,但是性能到底如何呢?又該如何評定呢?

這次我們談一談性能測試,看一看到底什麼樣才叫做高性能。

本文主要從以下幾個方面進行討論。

(1)性能測試是什麼?

(2)為什麼需要性能測試?

(3)性能測試如何做?

(4)有哪些性能測試的工具

性能測試是什麼?

老馬曾經說過,你想理解一件事物,首先必須先定義它。

這裡直接引用一下百科中的定義:

性能測試是通過自動化的測試工具模擬多種正常、峰值以及異常負載條件來對系統的各項性能指標進行測試。

性能測試的定義也不難理解,往往定義本身闡述了性能測試的作用。

為什麼需要性能測試?

如果你是一名開發、測試,平時接手過不少需求,可能性能測試接觸的也不多。

每一個需求,都有對應的功能性需求和肺功能性需求。

功能性需求是產品需求文檔中最直接的,需要實現的功能目標。簡稱,能用就行。

非功能性需求則要寬泛的多,架構設計是否合理?是否便於後期拓展?是否便於監控?程式碼實現是否優雅?文檔注釋是否完整?

就像你寫了一隻鳥,鳥頭做螺旋槳非能飛起來,但是在架構設計上可能是不合理的。

飛起來

一個查詢功能,用戶點擊查詢,10S 種才返回數據,功能上是滿足的,但是性能上是不能接受的。

線上的交易功能平時各方面都很棒,節假日高峰期直接系統就癱瘓了。

那如何避免這些問題出現在生產上呢?

這就需要上線之前,首先做好對應的性能測試,避免再生產上出現問題,帶來嚴重的生產事故。

性能要高,性能要硬,性能測試,又高又硬!

又高又硬

如何做好性能測試

做一件事情之前,我們首先要確定好自己的目標。

性能測試,到底要測試什麼?

有些類似於開發過程中的需求分析,常見的測試指標如下。

測試指標

響應時間

響應時間是指某個請求或操作從發出到接收到回饋所消耗的時間,包括應用伺服器(客戶端)處理時間、網路傳輸時間以及資料庫伺服器處理時間。

作為用戶而言,在頁面點擊查詢,等待了多久才能獲取結果,這個就是響應時間。

用戶不關心你後端經過了多少個服務,慢就是原罪。

對於微服務系統,鏈路監控就顯得比較重要。可以幫助我們快速定位到底慢在哪裡。

TPS/QPS

TPS(Transaction Per Second)是指單位時間(每秒)系統處理的事務量。

我看網上還有很多類似的概念:點擊量/點擊率、吞吐量/吞吐率、PV/UV,這裡不做贅述。

個人看來本質上 TPS/QPS 就是去壓測你應用的極限,當訪問量較大的時候,程式能否活下來?

這裡主要涉及到兩個概念:高性能和高可用。

我們後面會簡單討論下這兩點。

測試準備

明確了測試指標之後,就需要進行測試的準備。

環境準備:比如你想壓測資料庫,那就需要準備對應配置的資料庫資源。

腳本的準備:數據初始化腳本,調用腳本等。

這個可以類比開發過程中的程式碼開發。

ps: 性能壓測一般不是很常用,所以環境準備流程會比較長,這一點需要注意。

測試報告

當進行測試之後,測試的結果一定要給出一份報告出來。

是否通過壓測要求?

最高的 QPS 是多少?

這樣開發可以根據這份報告進行相應的優化。

如何提升程式性能

提升性能的內容寫一本書也不為過,這裡簡單羅列一些最常用的幾點:

(1)慢 SQL

一般程式如果響應時間較長,可以首先看一下慢 SQL。

看下是否需要增加索引,或者進行 SQL 優化。

(2)快取

針對查詢,性能提升最顯著的就是引入快取。

當然,引入快取會使架構變得複雜,這一點要結合自己的實際業務。

(3)硬體升級

如果程式優化的空間比較小,可以考慮升級一下硬體資源。

比如伺服器配置翻倍,資料庫配置翻倍。

什麼?你說公司沒錢升級?

沒錢升級做什麼壓測?

這個時候測試報告的作用就顯露了,直接用數據說話。

直接說 QPS 達不到生產要求,程式優化的空間很小,推薦硬體升級配置,升級到多少。

做人,要以德服人。

做測試,要用數據說話。

以德服人

常用的性能測試工具

測試最常用的工具當屬 jmeter。

除此之外,還有一些其他的工具:

LoadRunner、QALoad、SilkPerformer和Rational Performance Tester。

下面對幾個工具做下簡單介紹

jmeter

Apache JMeter 可以用於測試靜態和動態資源(Web動態應用程式)的性能。

它可以用於模擬伺服器、伺服器組、網路或對象上的負載,以測試其強度或分析不同負載類型下的總體性能。

LoadRunner

將負載測試集成到開發工具中:IDE、jUnit、nUnit、Jenkins、Selenium和Microsoft Visual Studio。

從12.55版本開始,您可以運行您的JMeter腳本,並在任何性能測試中集成JMeter和附加的腳本類型。

ps: 這個設計理念就非常好,可以和成熟的工具進行整合。站在巨人的肩膀上。

QALoad

QALoad是客戶/伺服器系統、企業資源配置(ERP)和電子商務應用的自動化負載測試工具。

QALoad可以模擬成百上千的用戶並發執行關鍵業務而完成對應用程式的測試,並針對所發現問題對系統性能進行優化,確保應用的成功部署。

ps: 這個工具本人沒有接觸過。

SilkPerformer

SilkPerformerV可以讓你在使用前,就能夠預測企業電子商務環境的行為—不受電子商務應用規模和複雜性影響。

可視化的用戶化、負載條件下可視化的內容校驗、實時的性能監視和強大的管理報告可以幫助您迅速將問題隔離,這樣,通過最小化測試周期、優化性能以及確保可伸縮性,加快了投入市場的時間,並保證了系統的可靠性。

Rational Performance Tester

作為 DevOps 方法的一部分,IBM Rational Performance Tester 幫助軟體測試團隊更早、更頻繁地進行測試。

它驗證 Web 和伺服器應用程式的可擴展性,確定系統性能瓶頸的存在和原因,並減少負載測試。

您的軟體測試團隊可以快速執行性能測試,分析負載對應用程式的影響。

ps: 這一款工具有 IBM 提供,品質值得信賴。

為開發量身定做的性能測試工具

這麼多工具可供使用,相信讀到這裡的小夥伴已經找到了自己心儀的測試工具。

別急,下面專門為做 java 開發的小夥伴們推薦一款性能測試工具。

男人有男人的浪漫,開發者當然也要有開發者的浪漫。

【男人的浪.jpg】

junitperf

作為一名開發者,老馬平時單元測試使用 junit 最多。

所以一直希望找到一款基於 junit 的性能壓測工具,後來也確實找到了。

//github.com/houbb/junitperf 是一款為 java 開發者設計的性能測試框架。

為什麼使用?

  • 可以和 Junit5 完美契合。

  • 使用簡單,便於項目開發過程中的測試實用。

  • 提供拓展,用戶可進行自定義開發。

特性

  • 支援 I18N

  • 支援多種報告生成方式,支援自定義

  • Junt5 完美支援,便於 Java 開發者使用

使用入門

maven 引入

<dependency>
    <groupId>com.github.houbb</groupId>
    <artifactId>junitperf</artifactId>
    <version>2.0.7</version>
</dependency>

入門例子

@JunitPerfConfig(duration = 1000)
public void helloTest() throws InterruptedException {
    Thread.sleep(100);
    System.out.println("Hello Junit5");
}

註解說明

@JunitPerfConfig 指定測試時的屬性配置。(必填項)

屬性 說明 類型 默認值 備註
threads 執行時使用多少執行緒執行 int 1
warmUp 準備時間 long 0 單位:毫秒
duration 執行時間 long 60_000(1分鐘) 單位:毫秒
latencyStatistics 統計實現 StatisticsCalculator DefaultStatisticsCalculator
reporter 報告實現 Reporter ConsoleReporter

使用如下:

/**
 * 2個執行緒運行。
 * 準備時間:1000ms
 * 運行時間: 2000ms
 * @throws InterruptedException if any
 */
@JunitPerfConfig(threads = 2, warmUp = 1000, duration = 2000)
public void junitPerfConfigTest() throws InterruptedException {
    System.out.println("junitPerfConfigTest");
    Thread.sleep(200);
}

@JunitPerfRequire 指定測試時需要達到的要求。(選填項)

屬性 說明 類型 默認值 備註
min 最佳的運行耗時 float -1 最快的運行耗時如果高於這個值,則視為失敗。單位:毫秒
max 平均的運行耗時 float -1 最壞的運行耗時如果高於這個值,則視為失敗。單位:毫秒
average 平均的運行耗時 float -1 平均的運行耗時如果高於這個值,則視為失敗。單位:毫秒
timesPerSecond 每秒的最小執行次數 int 0 如果低於這個最小執行次數,則視為失敗。
percentiles 對於執行耗時的限定 String[] {} percentiles={“20:220”, “30:250”}。20% 的數據執行耗時不得超過 220ms;30% 的數據執行耗時不得超過 250ms;

使用如下:

/**
 * 配置:2個執行緒運行。準備時間:1000ms。運行時間: 2000ms。
 * 要求:最快不可低於 210ms, 最慢不得低於 250ms, 平均不得低於 225ms, 每秒運行次數不得低於 4 次。
 * 20% 的數據不低於 220ms, 50% 的數據不得低於 230ms;
 *
 * @throws InterruptedException if any
 */
@JunitPerfConfig(threads = 2, warmUp = 1000, duration = 2000)
@JunitPerfRequire(min = 210, max = 250, average = 225, timesPerSecond = 4, percentiles = {"20:220", "50:230"})
public void junitPerfConfigTest() throws InterruptedException {
    System.out.println("junitPerfConfigTest");
    Thread.sleep(200);
}

測試報告

對應的測試報告生成方式也是多樣的,也允許用戶自定義。

基於控台日誌:

[INFO] [2020-06-16 20:05:53.618] [c.g.h.j.e.HelloWorldTest.helloTest] - Started at:  2020-06-16 20:05:52.512
[INFO] [2020-06-16 20:05:53.619] [c.g.h.j.e.HelloWorldTest.helloTest] - Invocations:  9
[INFO] [2020-06-16 20:05:53.620] [c.g.h.j.e.HelloWorldTest.helloTest] - Success:  9
[INFO] [2020-06-16 20:05:53.620] [c.g.h.j.e.HelloWorldTest.helloTest] - Errors:  0
[INFO] [2020-06-16 20:05:53.621] [c.g.h.j.e.HelloWorldTest.helloTest] - Thread Count:  1
[INFO] [2020-06-16 20:05:53.623] [c.g.h.j.e.HelloWorldTest.helloTest] - Warm up:  0ms
[INFO] [2020-06-16 20:05:53.623] [c.g.h.j.e.HelloWorldTest.helloTest] - Execution time:  1000ms
[INFO] [2020-06-16 20:05:53.624] [c.g.h.j.e.HelloWorldTest.helloTest] - Throughput:  9/s (Required: -1/s) - PASSED
[INFO] [2020-06-16 20:05:53.625] [c.g.h.j.e.HelloWorldTest.helloTest] - Memory cost:  16byte
[INFO] [2020-06-16 20:05:53.635] [c.g.h.j.e.HelloWorldTest.helloTest] - Min latency:  100.191414ms (Required: -1.0ms) - PASSED
[INFO] [2020-06-16 20:05:53.635] [c.g.h.j.e.HelloWorldTest.helloTest] - Max latency:  105.2382ms (Required: -1.0ms) - PASSED
[INFO] [2020-06-16 20:05:53.636] [c.g.h.j.e.HelloWorldTest.helloTest] - Avg latency:  101.43268ms (Required: -1.0ms) - PASSED

或者基於 HTML:

junitperf

小結

本文對性能測試做了最基本的介紹,讓小夥伴們對性能壓測有一個最基本的理解。

測試和開發一樣,都是一件費時費力,而且需要認真做才能做好的事情,其中的學問不是一篇就能說清的。

性能測試工具也比較多,本文重點介紹了專門為 java 開發者打造的 junitperf 工具。

下一節我們將從源碼角度,講解一下 junitperf 的實現原理。

我是老馬,期待與你的下次重逢。

開源地址://github.com/houbb/junitperf

在這裡插入圖片描述