在當今的軟件開發世界中,性能測試和負載測試至關重要。HTTP和gRPC是兩種常用的通信協議,許多系統依賴它們進行數據交換和服務調用。然而,選擇合適的測試工具來確保這些通信協議的性能和穩定性至關重要。本文將詳細探討使用k6測試HTTP和gRPC的優勢,吸引讀者從其他測試工具轉為使用k6工具。
k6簡介
k6 是一個現代化的開源負載和性能測試工具,使用go語言開發。它以其簡單易用、功能強大、可擴展性高以及對開發團隊友好而著稱。k6使用JavaScript作為腳本語言,使得開發人員能夠輕鬆上手,並且與現代開發工具鏈無縫集成。
k6測試HTTP的優勢
- 簡單易用的腳本語言,開發人員可以利用其熟悉的語法和工具鏈來編寫測試腳本。
- 強大的內置功能,k6內置了豐富的功能和模塊,能夠滿足各種複雜的HTTP測試需求。
- 高併發和高性能,能夠在單一節點上模擬數千個併發用户。
- 拓展能力和集成,k6與CI/CD工具鏈、監控系統和分析平台無縫集成,如Jenkins、GitLab、Prometheus和Grafana。這使得性能測試能夠更好地嵌入到開發和運維的生命週期中,實現自動化和持續監控。
k6測試gRPC的優勢
- 原生gRPC支持,使得開發人員能夠直接在k6腳本中編寫和執行gRPC調用。
- 跨語言和平台支持,輕鬆測試不同語言實現的gRPC服務。
- 高性能和低延遲,k6的高效執行引擎能夠模擬高強度的gRPC調用場景,驗證服務的性能瓶頸和極限。
與其他測試工具的比較
| 測試工具 | 説明 |
|---|---|
| Apache JMeter | Apache JMeter是一個歷史悠久的性能測試工具,支持多種協議的測試。然而,JMeter的配置和腳本編寫相對複雜,學習曲線較陡。與k6相比,JMeter的擴展性和現代集成能力也略顯不足。而k6的簡單易用性、現代化設計和豐富的擴展能力使其成為更具吸引力的選擇。 |
| Gatling | Gatling是另一個流行的性能測試工具,基於Scala語言。雖然Gatling在高併發測試方面表現出色,但其使用Scala編寫腳本對大多數開發人員來説並不友好。此外,Gatling對gRPC的支持相比k6也不夠完善。k6的JavaScript腳本和原生gRPC支持使其在易用性和功能性上更具優勢。 |
| Locust | Locust是一個使用Python編寫的負載測試工具,以其簡單靈活的腳本編寫方式受到歡迎。然而,Locust對高併發的支持不如k6高效,且對gRPC的支持也不如k6原生。另外,k6強大的圖表和報告功能也大大增強了測試結果的可視化和可解釋性。 |
k6作為一款現代化的開源負載和性能測試工具,憑藉其簡單易用的JavaScript腳本語言、強大的內置功能、高併發和高性能表現、以及與現代開發工具鏈的無縫集成,成為HTTP和gRPC測試的不二選擇。通過詳細對比其他測試工具,k6在易用性、功能性和擴展性方面展現了顯著優勢,提升系統的性能測試質量和效率,值得開發團隊認真考慮和採用。
測試 kratos、go-zero、sponge 三個微服務框架
主要壓測指標
- 吞吐量(Throughput):單位時間內處理的請求數量,通常以每秒請求數(Requests per Second,RPS)表示。
- 響應時間(Response Time):從發出請求到收到響應的時間,包括p95、p99、avg、min、max。
- 錯誤率(Error Rate):請求處理失敗或產生錯誤的比率。
- 資源利用率(Resource Utilization):包括cpu、內存、網絡帶寬等資源的使用情況。
壓測api
-
http
- 端口: 8080
- 路由: /api/v1/helloworld/qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
- 請求方法: GET
-
grpc
- 端口: 8282
- path: /helloworld.v1.Greeter/SayHello
- message: qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
- 類型: unary
注: 8080端口的路由/metrics是採集go程序的指標。
壓測工具
- k6: 用來壓測http服務。
- ghz: 用來壓測grpc服務。
壓測環境
因為不同的服務器硬件對性能測試結果不一樣,本次是在宿主機和虛擬機之間進行負載測試:
-
宿主機
- 硬件:R7 6800H CPU,16G內存
- 用途:運行工具k6和ghz測試http api和grpc api
-
VMware虛擬機
- 系統:centos 8
- 硬件:8核cpu、4G內存
- 用途:用於單獨運行kratos、go-zero、sponge創建的http和grpc服務
如果想要在自己的機器上進行負載測試,點擊查看壓測説明文檔。
壓測結果
50個併發,總共100萬個請求,壓測kratos、go-zero、sponge創建的http服務結果:
50個併發,總共100萬個請求,壓測kratos、go-zero、sponge創建的grpc服務結果:
kratos 創建的服務的壓測結果數據
kratos 版本 2.7.2
http 壓測結果數據
使用壓測工具k6,50個併發,總共100萬次請求的結果數據:
$ K6_PROMETHEUS_RW_SERVER_URL="http://192.168.3.37:9090/api/v1/write" K6_PROMETHEUS_RW_TREND_STATS="min,max,avg,p(95),p(99)" K6_PROMETHEUS_RW_PUSH_INTERVAL=1s k6 run -u 50 -i 1000000 -o experimental-prometheus-rw http-load-test.js
execution: local
script: http-load-test.js
output: Prometheus remote write (http://192.168.3.37:9090/api/v1/write)
scenarios: (100.00%) 1 scenario, 50 max VUs, 10m30s max duration (incl. graceful stop):
* default: 1000000 iterations shared among 50 VUs (maxDuration: 10m0s, gracefulStop: 30s)
✓ status is 200
checks.........................: 100.00% ✓ 1000000 ✗ 0
data_received..................: 137 MB 2.3 MB/s
data_sent......................: 115 MB 2.0 MB/s
http_req_blocked...............: avg=1.68µs min=0s med=0s max=10.12ms p(90)=0s p(95)=0s
http_req_connecting............: avg=262ns min=0s med=0s max=10.12ms p(90)=0s p(95)=0s
http_req_duration..............: avg=2.86ms min=0s med=2.01ms max=47.44ms p(90)=6.62ms p(95)=8.68ms
{ expected_response:true }...: avg=2.86ms min=0s med=2.01ms max=47.44ms p(90)=6.62ms p(95)=8.68ms
http_req_failed................: 0.00% ✓ 0 ✗ 1000000
http_req_receiving.............: avg=20.56µs min=0s med=0s max=4.68ms p(90)=0s p(95)=0s
http_req_sending...............: avg=8.01µs min=0s med=0s max=3.77ms p(90)=0s p(95)=0s
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=2.83ms min=0s med=2ms max=47.44ms p(90)=6.58ms p(95)=8.64ms
http_reqs......................: 1000000 17085.130811/s
iteration_duration.............: avg=2.91ms min=0s med=2.02ms max=47.44ms p(90)=6.68ms p(95)=8.76ms
iterations.....................: 1000000 17085.130811/s
vus............................: 50 min=50 max=50
vus_max........................: 50 min=50 max=50
running (00m58.5s), 00/50 VUs, 1000000 complete and 0 interrupted iterations
default ✓ [======================================] 50 VUs 00m58.5s/10m0s 1000000/1000000 shared iters
壓測http api指標的grafana界面:
採集到的服務程序指標的grafana界面:
grpc 壓測結果數據
使用壓測工具ghz,50個併發,總共100萬次請求的結果數據。
grpc api壓測結果數據:
採集到的服務程序指標的grafana界面:
go-zero 創建的服務的壓測結果數據
go-zero 版本 1.6.3
http 壓測結果數據
使用壓測工具k6,50個併發,總共100萬次請求的結果數據:
$ K6_PROMETHEUS_RW_SERVER_URL="http://192.168.3.37:9090/api/v1/write" K6_PROMETHEUS_RW_TREND_STATS="min,max,avg,p(95),p(99)" K6_PROMETHEUS_RW_PUSH_INTERVAL=1s k6 run -u 50 -i 1000000 -o experimental-prometheus-rw http-load-test.js
execution: local
script: http-load-test.js
output: Prometheus remote write (http://192.168.3.37:9090/api/v1/write)
scenarios: (100.00%) 1 scenario, 50 max VUs, 10m30s max duration (incl. graceful stop):
* default: 1000000 iterations shared among 50 VUs (maxDuration: 10m0s, gracefulStop: 30s)
✓ status is 200
checks.........................: 100.00% ✓ 1000000 ✗ 0
data_received..................: 222 MB 3.5 MB/s
data_sent......................: 115 MB 1.8 MB/s
http_req_blocked...............: avg=1.67µs min=0s med=0s max=8.64ms p(90)=0s p(95)=0s
http_req_connecting............: avg=243ns min=0s med=0s max=8.64ms p(90)=0s p(95)=0s
http_req_duration..............: avg=3.08ms min=0s med=2.05ms max=124.92ms p(90)=6.78ms p(95)=9.13ms
{ expected_response:true }...: avg=3.08ms min=0s med=2.05ms max=124.92ms p(90)=6.78ms p(95)=9.13ms
http_req_failed................: 0.00% ✓ 0 ✗ 1000000
http_req_receiving.............: avg=21.31µs min=0s med=0s max=5.89ms p(90)=0s p(95)=0s
http_req_sending...............: avg=8.13µs min=0s med=0s max=5.2ms p(90)=0s p(95)=0s
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=3.05ms min=0s med=2.04ms max=124.92ms p(90)=6.75ms p(95)=9.09ms
http_reqs......................: 1000000 15887.422209/s
iteration_duration.............: avg=3.13ms min=0s med=2.08ms max=124.92ms p(90)=6.85ms p(95)=9.21ms
iterations.....................: 1000000 15887.422209/s
vus............................: 50 min=50 max=50
vus_max........................: 50 min=50 max=50
running (01m02.9s), 00/50 VUs, 1000000 complete and 0 interrupted iterations
default ✓ [======================================] 50 VUs 01m02.9s/10m0s 1000000/1000000 shared iters
壓測http api指標的grafana界面:
採集到的服務程序指標的grafana界面:
grpc 壓測結果數據
使用壓測工具ghz,50個併發,總共100萬次請求的結果數據。
grpc api壓測結果數據:
採集到的服務程序指標的grafana界面:
sponge 創建的服務的壓測結果數據
sponge 版本 1.7.0
http 壓測結果數據
使用壓測工具k6,50個併發,總共100萬次請求的結果數據:
$ K6_PROMETHEUS_RW_SERVER_URL="http://192.168.3.37:9090/api/v1/write" K6_PROMETHEUS_RW_TREND_STATS="min,max,avg,p(95),p(99)" K6_PROMETHEUS_RW_PUSH_INTERVAL=1s k6 run -u 50 -i 1000000 -o experimental-prometheus-rw http-load-test.js
execution: local
script: http-load-test.js
output: Prometheus remote write (http://192.168.3.37:9090/api/v1/write)
scenarios: (100.00%) 1 scenario, 50 max VUs, 10m30s max duration (incl. graceful stop):
* default: 1000000 iterations shared among 50 VUs (maxDuration: 10m0s, gracefulStop: 30s)
✓ status is 200
checks.........................: 100.00% ✓ 1000000 ✗ 0
data_received..................: 181 MB 3.2 MB/s
data_sent......................: 115 MB 2.0 MB/s
http_req_blocked...............: avg=1.75µs min=0s med=0s max=10.2ms p(90)=0s p(95)=0s
http_req_connecting............: avg=305ns min=0s med=0s max=10.2ms p(90)=0s p(95)=0s
http_req_duration..............: avg=2.74ms min=0s med=2.04ms max=59.21ms p(90)=5.9ms p(95)=7.67ms
{ expected_response:true }...: avg=2.74ms min=0s med=2.04ms max=59.21ms p(90)=5.9ms p(95)=7.67ms
http_req_failed................: 0.00% ✓ 0 ✗ 1000000
http_req_receiving.............: avg=20.85µs min=0s med=0s max=8.54ms p(90)=0s p(95)=0s
http_req_sending...............: avg=8.55µs min=0s med=0s max=6.16ms p(90)=0s p(95)=0s
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=2.72ms min=0s med=2.02ms max=58.69ms p(90)=5.87ms p(95)=7.63ms
http_reqs......................: 1000000 17740.077322/s
iteration_duration.............: avg=2.81ms min=0s med=2.07ms max=59.21ms p(90)=5.97ms p(95)=7.74ms
iterations.....................: 1000000 17740.077322/s
vus............................: 50 min=50 max=50
vus_max........................: 50 min=50 max=50
running (00m56.4s), 00/50 VUs, 1000000 complete and 0 interrupted iterations
default ✓ [======================================] 50 VUs 00m56.4s/10m0s 1000000/1000000 shared iters
壓測http api指標的grafana界面:
採集到的服務程序指標的grafana界面:
grpc 壓測結果數據
使用壓測工具ghz,50個併發,總共100萬次請求的結果數據。
grpc api的壓測結果數據:
採集到的服務程序指標的grafana界面:
注:上面 kratos、go-zero、sponge 測試http使用的是k6,測試grpc使用壓測工具ghz,主要是為了更好的併發性能,這是測試 kratos、go-zero、sponge 完整代碼 https://github.com/zhufuyi/microservices_framework_benchmark,可以在這裏把ghz改為grpc測試。