前言:
最近的 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 執行環境】