Table of contents
1 JMeter 簡介
Apache JMeter 係一款專門做 API performance testing 既工具,佢可以用 multithreading 去模擬多個 users(或者 downstream clients)同時 request 需要測試既 HTTP APIs,然後佢會紀錄低 HTTP response、throughput、耗時等等既數據。
1.1 下載 JMeter
2 動手做
我地會寫一個 Spring Boot web application,裡面會有以下既 HTTP APIs,我地既 JMeter script 都會根據相同既次序黎 loop HTTP API calls:
次序 | HTTP API | 作用 | JMeter 測試須知 |
---|
1 | GET /api/uppercase/{value} | 將 {value} 變成大楷然後返回。 | 用 User Parameters 既隨機數據作為 request input;用 BeanShell PostProcessor 將 response body save 低。 |
2 | GET /api/toJson/{value} | 將 {value} 放入一個 object 裡面然後返回。 | 用 JSR223 PostProcessor 將 response body 既某個 JSON field save 低。 |
3 | GET /api/lowercase/{value} | 將 {value} 變成細楷然後返回。 | N/A |
2.1 建立 Spring Boot web microservice
2.1.1 Maven dependencies
我地會加入 Spring Security 去令個 microservice 既 HTTP requests respond 得慢啲。
1<parent>
2 <groupId>org.springframework.boot</groupId>
3 <artifactId>spring-boot-starter-parent</artifactId>
4 <version>3.3.4</version>
5</parent>
6
7<dependencies>
8 <dependency>
9 <groupId>org.springframework.boot</groupId>
10 <artifactId>spring-boot-starter-web</artifactId>
11 </dependency>
12 <dependency>
13 <groupId>org.springframework.boot</groupId>
14 <artifactId>spring-boot-starter-security</artifactId>
15 </dependency>
16</dependencies>
2.1.2 寫 Java code
SampleController.java
:
1@RestController
2@RequestMapping("/api")
3public class SampleController {
4
5 @GetMapping("/uppercase/{value}")
6 public String uppercase(@PathVariable(name = "value", required = true) String value) {
7 return value.toUpperCase();
8 }
9
10 @GetMapping("/toJson/{value}")
11 public MyDto toJson(@PathVariable(name = "value", required = true) String value) {
12 return new MyDto(value, Arrays.asList(new MyDto2(3L, new BigDecimal("5.6"))));
13 }
14
15 @GetMapping("/lowercase/{value}")
16 public String lowercase(@PathVariable(name = "value", required = true) String value) {
17 return value.toLowerCase();
18 }
19}
2.1.3 Application 配置
spring:
security:
user:
name: mick
password: foobar
2.2 建立 JMeter JMX 檔
我地會用 JMeter 既介面幫我地建立 JMX 檔,我地會將個 JMX 檔保存做 jmeter.jmx
。
2.2.1 新增 Thread Group
- Right-click
Test Plan
> Add > Threads (Users) > Thread Group。
- 將 Number of Threads (users) 改成
${__P(threadCount, 500)}
。
- 將 Ramp-up period (seconds) 改成
0
。
- 將 Loop count 改成
${__P(loopCount, 200)}
。
2.2.2 新增 HTTP Authorization Manager
因為我地有用到 Spring Security 去做 basic authentication,所以我地要加入 HTTP authorization manager:
- Right-click
Thread Group
> Add > Config Element > HTTP Authorization Manager。
- 撳下面「Add」。
- Username 輸入
mick
。
- Password 輸入
foobar
。
2.2.3 新增 User Parameters
我地可以用 user parameters 黎定義 variables。
- Right-click
Thread Group
> Add > Pre Processors > User Parameters。
- 啟用「Update Once Per Iteration」。
- 撳下面「Add Variable」。
- Name 輸入
myRandomVal
。
- User_1 輸入
${__RandomString(10, abcdefghijklmnopqrstuvwxyz)}
。
註:
- 我地應該用 user parameters 而唔係 user-defined variables。
- 因為 user parameters 喺每個 iteration/loop 都會 reset;相反,user-defined variables 一直都會維持一樣既 values。
2.2.4 新增 HTTP Request
- 新增第
1
個 HTTP request。
- Right-click
Thread Group
> Add > Sampler > HTTP Request。
- 將 Name 改成
HTTP Request - /api/uppercase/{value}
。
- Protocol 輸入
http
。
- Server Name or IP 輸入
localhost
。
- Port Number 輸入
8080
。
- Path 輸入
/api/uppercase/${myRandomVal}
。
- 新增第
2
個 HTTP request。
- Right-click 岩岩整既 HTTP request > Duplicate。
- 將 Name 改成
HTTP Request - /api/toJson/{value}
。
- 將 Path 改成
/api/toJson/${myTempVal}
。
- 新增第
3
個 HTTP request。
- Right-click 岩岩整既 HTTP request > Duplicate。
- 將 Name 改成
HTTP Request - /api/lowercase/{value}
。
- 將 Path 改成
/api/lowercase/${myTempVal}
。
2.2.5 新增 BeanShell PostProcessor
- Right-click
HTTP Request - /api/uppercase/{value}
> Add > Post Processors > BeanShell PostProcessor。
- Script 輸入
vars.put("myTempVal", new String(data));
。
2.2.6 新增 JSR223 PostProcessor
- Right-click
HTTP Request - /api/toJson/{value}
> Add > Post Processors > JSR223 PostProcessor。
- Script 輸入
vars.put("myTempVal", prev.items[0].productName);
。
2.2.7 新增 View Results Tree
- Right-click
Thread Group
> Add > Listener > View Results Tree。
2.2.8 新增 Summary Report
- Right-click
Thread Group
> Add > Listener > Summary Report。
3 測試
我地配置左:
500
個 users
200
個 loops
3
個 HTTP requests
總共就會發起 500 × 200 × 3
即係 300000
個 HTTP requests。
3.1 用介面執行
- 撳上面 menu bar 下一行既綠色「▶️」掣開始 performance testing。
- 等佢運行一陣。
- 檢視 Views Results Tree,我地會見到所有 HTTP responses 都係綠色,即係成功。
- 檢視 Summary Report,我地會見到「TOTAL」既 throughput。
3.2 用 command 執行
rmdir /s /q "output"
mkdir "output"
jmeter -n -t "jmeter.jmx" -l "./output/result.jtl" -e -o "./output/dashboard" -J threadCount=500 -J loopCount=200
執行完之後,JMeter 會生成:
- HTML dashboard 檔案,我地可以用瀏覽器打開睇。
- JTL 檔案,係包含所有 HTTP requests 既結果既 raw data,裡面係 CSV 格式。
註:
- 根據以上結果,CLI 模式(又叫 non-GUI 模式)既 throughput 居然會低過 GUI 模式。
- 不過,官方話我地係應該以 CLI 模式既結果為準。
4 參考資料