Taurus.MVC 效能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本

路过秋天發表於2024-04-10

前言:

最近的 Taurus.MVC 版本,對效能這一塊有了不少最佳化,因此準備進行一下壓測,來測試並記錄一下 Taurus.MVC 框架的效能,以便後續持續最佳化改進。

今天先壓測 .NET Core 版本,後續有時間再壓測一下.NET 版本。

下面來看不同場景下的壓測結果,以下測試結果會由兩臺電腦進行分別測試。

一、舊電腦環境:

CPU :Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz
核心: 6
邏輯處理器: 6
記憶體:16G

程式在 .NET8 編繹,以 Kestrel 為主機直接執行在 Window 環境:

1、測試 Window 11 下,單機ab工具壓測:

由於ab工具佔用資源不多,發起的併發能力也有限,先用它進行本機壓測,試試水。

ab的版本資訊:

A、先測試單執行緒的執行效能(簡單介面返回,控制檯帶日誌輸出):

ab -n 100000 -c 1 http://192.168.100.102:51996/api/hello

測試結果:併發數1,qps = 3263

Server Software:
Server Hostname:        192.168.100.102
Server Port:            51996

Document Path:          /api/hello
Document Length:        24 bytes

Concurrency Level:      1
Time taken for tests:   30.641 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      13900000 bytes
HTML transferred:       2400000 bytes
Requests per second:    3263.63 [#/sec] (mean)
Time per request:       0.306 [ms] (mean)
Time per request:       0.306 [ms] (mean, across all concurrent requests)
Transfer rate:          443.01 [Kbytes/sec] received

看一下程式執行的時間:

從程式列印的日誌上看,介面執行時間僅有0.03毫秒,理論值單執行緒壓測是可以達到1000/0.0345= 28089,

去掉控制器日誌輸出,還能再提升1下,再配置個64核cpu,就是傳說中的輕輕鬆鬆的單機百萬qps了。

B、我們調整一下引數,看看ab在單機下能壓出多少來(簡單介面返回,控制檯帶日誌輸出):

ab -n 100000 -c 2 http://192.168.100.102:51996/api/hello

測試結果:

Concurrency Level:      2
Time taken for tests:   18.187 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      13900000 bytes
HTML transferred:       2400000 bytes
Requests per second:    5498.28 [#/sec] (mean)
Time per request:       0.364 [ms] (mean)
Time per request:       0.182 [ms] (mean, across all concurrent requests)
Transfer rate:          746.35 [Kbytes/sec] received

沒辦法,只能壓 2 個併發連結,CPU 跑滿了,程式佔40%多,ab也佔了40%多,說好的ab不吃資源的,直接cpu拉走一半,呵呵。

C、我們關閉日誌輸出,重新看看上面的兩個能測試出多少(簡單介面返回,控制檯無日誌輸出):

我們新增以下程式碼,關閉 Kestrel 預設的控制檯資訊輸出:

services.AddLogging(op => op.SetMinimumLevel(LogLevel.None));

【後續的測試,都保持控制器日誌關閉】

重新編繹後,進行重新測試:

測試結果:併發數1,qps = 3595

Concurrency Level:      1
Time taken for tests:   2.781 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1390000 bytes
HTML transferred:       240000 bytes
Requests per second:    3595.51 [#/sec] (mean)
Time per request:       0.278 [ms] (mean)
Time per request:       0.278 [ms] (mean, across all concurrent requests)
Transfer rate:          488.06 [Kbytes/sec] received

關閉日誌,提升了300多,後續測試,將會保持控制檯日誌的關閉。

測試結果:併發數 2,qps = 5765

Concurrency Level:      2
Time taken for tests:   1.734 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1390000 bytes
HTML transferred:       240000 bytes
Requests per second:    5765.77 [#/sec] (mean)
Time per request:       0.347 [ms] (mean)
Time per request:       0.173 [ms] (mean, across all concurrent requests)
Transfer rate:          782.66 [Kbytes/sec] received

接下來,我們將介面調整一下,單純的返回 Hello World 沒啥看頭,改成常規一些。

D、使用 CYQ.Data 讀資料庫,輸出 Json,來看看壓測結果(讀資料庫介面,控制檯無日誌輸出)

測試程式碼:

public void Hello(string msg)
{
    string conn = "server=.;database=MSLog;uid=sa;pwd=123456";
    using (MProc proc = new MProc("select top 1 * from SysLogs", conn))
    {
        Write(proc.ExeJson());
    }
}

執行結果:返回一條資料:

下面直接進行壓測結果:併發數 2 ,qps = 5470,和未關閉日誌輸出時差不多。

Concurrency Level:      2
Time taken for tests:   1.828 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      10810000 bytes
HTML transferred:       9590000 bytes
Requests per second:    5470.23 [#/sec] (mean)
Time per request:       0.366 [ms] (mean)
Time per request:       0.183 [ms] (mean, across all concurrent requests)
Transfer rate:          5774.73 [Kbytes/sec] received

小結:

從上面的測試結果,觀察CPU中可以看出,ab 這個工具,吃 cpu 資源不說,其併發數量也有限。

下面更換 wrk 進行測試,由於 wrk 只能在 linux 中執行,因此在本機上,開啟了虛擬機器。

2、測試 Window 11 下,虛擬機器wrk工具壓測:(讀資料庫輸出,控制檯無日誌輸出)

虛擬機器環境:

CPU :Intel(R) Core(TM) i5-9400 CPU @ 2.90GHz
核心: 2
邏輯處理器: 2
記憶體:4G

分完虛擬機器後,本機就剩下 4 核了,再去掉開啟工作管理員,就佔掉了10%的cpu,我了個去,當個3核用了。

不過問題不大,儘管測就是了,為了保持介面的通用性,繼續使用讀資料庫輸出 Json 的介面:

先使用1執行緒1併發測試試試水:

 wrk -t 1 -c1 -d 10s http://192.168.100.102:51996/api/hello

測試結果:qps = 1518

Running 10s test @ http://192.168.100.102:51996/api/hello
  1 threads and 1 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     2.76ms   14.97ms 200.26ms   98.45%
    Req/Sec     1.54k   402.67     2.62k    73.74%
  15294 requests in 10.07s, 16.07MB read
Requests/sec:   1518.47
Transfer/sec:      1.60MB

測試過程,透過虛擬機器(top 指令)和Windows(工作管理員)觀察 cpu,發現沒怎麼動,看來 wrk 要跑滿效能,得加量。

我們給虛擬機器分了2個核,不能浪費,要跑滿它,於是不斷調整引數:

wrk -t 2 -c4096 -d 10s http://192.168.100.102:51996/api/hello

測試結果:qps = 23303

Running 10s test @ http://192.168.100.102:51996/api/hello
  2 threads and 4096 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    28.17ms   19.27ms 307.26ms   82.72%
    Req/Sec    11.63k    12.33k   37.01k    77.53%
  234427 requests in 10.06s, 246.37MB read
  Socket errors: connect 3077, read 0, write 0, timeout 0
Requests/sec:  23303.58
Transfer/sec:     24.49MB

從測試結果觀察,wrk 更能壓測出效能的極限,當然,這是 wrk 的極限,不是程式的極限。

因為整個壓測過程,程式只佔了30%左右的cpu,但沒辦法,cpu 讓其它資源給吃光了。

我們知道,.NET Core 的程式,跑在 Linux 下,能會有更優的效能,不過不急先。

由於本機資源有限,干擾程式較多,這裡打算拿出我的新電腦,來進行重新測試,看看程式在新電腦的表現如何。

二、新電腦環境:

CPU    13th Gen Intel(R) Core(TM) i5-13600KF
核心:    14
邏輯處理器: 20
記憶體:64G

接下來,我們看看新電腦的表現如何,使用一樣的程式:

1、測試 Window 11 下,單機ab工具壓測:

A、先測試單執行緒的執行效能(簡單介面返回,控制檯無日誌輸出):

ab -n 100000 -c 1 http://192.168.100.102:51996/api/hello

測試結果:併發數1,qps = 11389

Concurrency Level:      1
Time taken for tests:   0.878 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1410000 bytes
HTML transferred:       260000 bytes
Requests per second:    11389.76 [#/sec] (mean)
Time per request:       0.088 [ms] (mean)
Time per request:       0.088 [ms] (mean, across all concurrent requests)
Transfer rate:          1568.32 [Kbytes/sec] received

B、我們調整一下引數,看看ab在單機下能壓出多少來(簡單介面返回,控制檯無日誌輸出):

ab -n 100000 -c 4 http://192.168.100.101:51996/api/hello

測試結果:併發數4,qps = 18247

Concurrency Level:      4
Time taken for tests:   5.480 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      14100000 bytes
HTML transferred:       2600000 bytes
Requests per second:    18247.09 [#/sec] (mean)
Time per request:       0.219 [ms] (mean)
Time per request:       0.055 [ms] (mean, across all concurrent requests)
Transfer rate:          2512.54 [Kbytes/sec] received

看來 ab 不行啊,壓不出結果,程式的cpu才跑了不到2%。

小結:

雖然 ab 壓測不夠力,但從單執行緒的測試結果可以看出,新電腦的cpu執行效率是舊電腦效能的3倍左右,效率拉滿。

以此看出,平時在採購雲伺服器時,也得順帶關注一下CPU的型號,好的型號,能提升執行效率,提高併發。

2、測試 Window 11 下,虛擬機器wrk工具壓測:(簡單介面,控制檯無日誌輸出)

虛擬機器環境:

CPU    13th Gen Intel(R) Core(TM) i5-13600KF
核心:    2
邏輯處理器: 2
記憶體:4G

先給虛擬機器2核,本機剩下 12 核了,可以好好壓一下了。

wrk -t 1 -c 1 -d 10s http://192.168.100.101:51996/api/hello

測試結果:1併發,qps = 14084

Running 10s test @ http://192.168.100.101:51996/api/hello
  1 threads and 1 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     6.43ms   29.09ms 218.31ms   95.10%
    Req/Sec    14.43k     3.27k   17.98k    91.84%
  141377 requests in 10.04s, 21.71MB read
Requests/sec:  14084.98
Transfer/sec:      2.16MB

和 ab 一樣,一個連結併發壓不出什麼效果,加大效果看看。

wrk -t 8 -c 2048 -d 10s http://192.168.100.101:51996/api/hello

測試結果:qps = 84306

Running 10s test @ http://192.168.100.101:51996/api/hello
  28 threads and 2048 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    11.40ms   10.81ms 222.31ms   86.60%
    Req/Sec     5.35k     3.03k   18.81k    69.09%
  850042 requests in 10.08s, 130.52MB read
  Socket errors: connect 1051, read 0, write 100, timeout 0
Requests/sec:  84306.38
Transfer/sec:     12.94MB

壓測試過程,觀察兩個cpu,虛擬機器(110%-130%,2核還沒跑滿),程式只跑16%-20%,整體40-50%左右,感覺還能往上跑。

估計是壓力不夠,試著分給虛擬機器多2核,看看有沒有效果。

虛擬機器環境:

CPU    13th Gen Intel(R) Core(TM) i5-13600KF
核心:    4
邏輯處理器: 4
記憶體:8G

繼續壓測試:

wrk -t18 -c 1400 -d 60s http://192.168.100.101:51996/api/hello

測試結果:qps = 105462

Running 1m test @ http://192.168.100.101:51996/api/hello
  18 threads and 1400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    10.02ms   10.05ms 267.70ms   90.26%
    Req/Sec     6.68k     3.31k   17.16k    62.65%
  6339226 requests in 1.00m, 0.95GB read
  Socket errors: connect 383, read 0, write 25, timeout 0
Requests/sec: 105462.01
Transfer/sec:     16.19MB

之前壓測時間在10s-20s,qps 都在9萬多,把壓測時間拉長到1分鐘,超過了10萬了。

看來把壓測時間拉長,qps 會高一點。

測試過程中,虛擬機器CPU(在180%左右,給了4核,也不頂用,沒能跑滿),程式佔用CPU(20%左右)。

還是跑不滿,沒辦法,壓力上不去了,只好換個口味測試。

重新壓測 CYQ.Data 讀資料庫轉Json輸出的介面(資料庫mssql2012 安裝在Window 11 本機):

介面的呼叫輸出:

進行壓測:

wrk -t18 -c 1200 -d 60s http://192.168.100.101:51996/api/hellodb

測試結果:qps = 73122

Running 1m test @ http://192.168.100.101:51996/api/hellodb
  18 threads and 1200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    47.62ms   86.25ms   1.15s    85.85%
    Req/Sec     4.61k     2.10k   17.56k    68.95%
  4394613 requests in 1.00m, 4.51GB read
  Socket errors: connect 185, read 0, write 24, timeout 1
Requests/sec:  73122.19
Transfer/sec:     76.85MB

再換一個,直接壓 MVC 介面,看看效果。

這是壓測試的 Taurus.MVC 的主介面:

修改壓測路徑:

wrk -t18 -c 1200 -d 60s http://192.168.100.101:51996/home/index

測試結果:qps = 39349

Running 1m test @ http://192.168.100.101:51996/home/index
  18 threads and 1200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    82.78ms  160.41ms   1.94s    87.98%
    Req/Sec     2.33k     0.94k    7.67k    67.93%
  2364614 requests in 1.00m, 8.75GB read
  Socket errors: connect 185, read 0, write 0, timeout 918
Requests/sec:  39349.00
Transfer/sec:    149.13MB

這時候觀察,雖然取得了不錯的結果,但 CPU 跑滿100%了,也有918個超時,看來呈現的載入與呈現,很消耗計算量。

到了最後的步驟了,.NET Core 程式,還是得放到 Linux 系統下跑看看效果 ,複製一臺虛擬機器,用來部署 .NET Core 程式。

3、測試 CentOS 7 下,虛擬機器 wrk 工具壓測:

新的虛擬機器環境:

CPU    13th Gen Intel(R) Core(TM) i5-13600KF
核心:    8
邏輯處理器: 8
記憶體:8G

1、測試介面:直接壓測 CYQ.Data 讀資料庫轉Json輸出的介面(資料庫mssql2012安裝在Window 11 系統):

wrk -t18 -c 1600 -d 60s http://192.168.100.111:51996/api/hellodb

測試結果:qps = 80831

Running 1m test @ http://192.168.100.111:51996/api/hellodb
  18 threads and 1600 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    35.63ms   74.47ms   1.03s    87.97%
    Req/Sec     4.83k     2.67k   18.55k    69.03%
  4856997 requests in 1.00m, 4.98GB read
  Socket errors: connect 581, read 0, write 0, timeout 0
Requests/sec:  80831.35
Transfer/sec:     84.95MB

觀察CPU:壓測虛擬機器(130%左右,用了1.3個核左右),應用程式虛擬機器(450%左右,用了4.5個核左右)

2、測試介面:直接測試簡單介面

wrk -t18 -c 1600 -d 60s http://192.168.100.111:51996/api/hello

測試結果:qps = 105994

Running 1m test @ http://192.168.100.111:51996/api/hello
  18 threads and 1600 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     9.16ms    4.84ms 212.60ms   79.65%
    Req/Sec     6.32k     3.65k   27.06k    57.03%
  6424281 requests in 1.00m, 0.95GB read
  Socket errors: connect 581, read 0, write 0, timeout 0
Requests/sec: 106908.28
Transfer/sec:     16.21MB

觀察CPU:和上一個結果差不多,只用了虛擬機器的50%左右,就是部署在Linux 上,隨便調整引數,都輕鬆10萬+。

總結:

對於 API 壓測:

舊電腦輕鬆就打滿CPU,主要是被ab和其它應用吃了資源,所以壓測上不去,去掉虛擬機器兩核後,在讀資料庫轉Json輸出的情況下,壓出了2萬3的qps。

新電腦上限太高,wrk 都壓不住,上10萬+了,CPU也才20%左右,可見一個高效的CPU對併發的提升是多麼明顯。

新電腦在讀資料庫轉Json輸出的情況下,也有8萬+的qps,這個3倍左右的效率,明顯的有點明顯了。

最後部署在 Linux,可以感覺效能明顯比 Window 執行高一些,Window 需要小小調優引數才10萬+,而 Linux 上隨便調都10萬+。

但因wrk給的壓力也有限,10萬+後無法再測試了,聽說 ulimit -n 命令可以解鎖,發起更大的併發,這個下次再試了。

對於 MVC 壓測:

明顯感覺 MVC 的計算量大了很多,wrk 提供的壓力已足夠跑滿CPU,極限跑出近4萬的qps,感覺後續應該還能小最佳化一下。

整體來說,今天的壓力測試結果,除了壓測試MVC介面,CPU 壓滿了,而壓測試API,CPU 都沒能跑滿整機的30%,心累啊,先就到這裡了。

附本文的執行程式:TaurusMVC執行程式下載 - 解壓後可直接執行 Taurus.View.exe,歡迎下載自行測試【需要.NET 8 執行環境】

相關文章