"distance": 1003784333
ghz 壓測工具,是這麼自我介紹的:
Simple gRPC benchmarking and load testing tool inspired by hey and grpcurl.
所以,從命令列參數及統計結果上,都可看出它們的影響。
譬如說,我們可將 proto 檔案的路徑寫在 --import-path
中、將 proto 檔案名稱寫在 --proto
中、將參數寫在 --data
中,再呼叫 server 的遠端程序:
$ ghz --insecure -z 20s \
--data '[{"latitude":-460000000,"longitude":-1160000000},{"latitude":720000000,"longitude":-540000000}]' \
--import-paths ./routeguide \
--proto route_guide.proto \
--call routeguide.RouteGuide.RecordRoute \
127.0.0.1:10000
壓測 20 秒,結果如下:
Response time histogram:
0.123 [1] |
5.147 [543463] |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎
10.170 [4297] |
15.194 [271] |
20.217 [8] |
25.241 [3] |
30.264 [1] |
35.288 [0] |
40.311 [0] |
45.335 [0] |
50.358 [1] |
Latency distribution:
10 % in 0.90 ms
25 % in 1.21 ms
50 % in 1.58 ms
75 % in 2.04 ms
90 % in 2.66 ms
95 % in 3.24 ms
99 % in 4.93 ms
Status code distribution:
[Canceled] 33 responses
[Unavailable] 4 responses
[OK] 548045 responses
Error distribution:
[33] rpc error: code = Canceled desc = grpc: the client connection is closing
[4] rpc error: code = Unavailable desc = transport is closing
同樣的,我們也可將事先備妥的資料檔餵給 ghz。像是含有 100 筆資料的 testdata.json
:
$ ghz --insecure --data=@ -z 20s \
--import-paths ./routeguide \
--proto route_guide.proto \
--call routeguide.RouteGuide.RecordRoute \
127.0.0.1:10000 \
< testdata.json
壓測 20 秒,結果如下:
Response time histogram:
0.126 [1] |
2.915 [772021] |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎
5.705 [15003] |∎
8.495 [1000] |
11.285 [458] |
14.074 [95] |
16.864 [10] |
19.654 [12] |
22.444 [3] |
25.233 [5] |
28.023 [40] |
Latency distribution:
10 % in 0.65 ms
25 % in 0.86 ms
50 % in 1.11 ms
75 % in 1.42 ms
90 % in 1.88 ms
95 % in 2.30 ms
99 % in 3.57 ms
Status code distribution:
[OK] 788648 responses
[Canceled] 32 responses
Error distribution:
[32] rpc error: code = Canceled desc = grpc: the client connection is closing
實驗二:不需搭配 proto 檔
使用前,每次都要先備妥待測程式的 proto 檔,其實也滿麻煩的。萬一複雜的 proto 檔案又去 import 其他 proto 檔 ,可能就得條列一堆 -import-path
或 --import-path
命令列參數給 gRPCurl 及 ghz。
有沒有省力一點的方法?
有的,就是透過 server reflection 功能。
Server reflection
我以這次的範例程式 server-new 為例,說明如何加上 server reflection 功能。
首先,請加上 google.golang.org/grpc/reflection
套件:
import "google.golang.org/grpc/reflection"
接著,在 grpcServer.Serve
之前,呼叫 reflection.Register
:
grpcServer := grpc.NewServer(opts...)
//...
// Register reflection service on gRPC server.
reflection.Register(grpcServer)
grpcServer.Serve(lis)
只需要這兩個步驟,你的 gRPC 程式本身就具有 server reflection 功能,對方不再需要 proto 檔案就能直接進行遠端呼叫。
針對新版的 server-new 來實驗看看吧。
gRPCurl
我們可用 list
指令查詢 server-new 提供哪些服務:
$ grpcurl -plaintext 127.0.0.1:20000 list
grpc.reflection.v1alpha.ServerReflection
routeguide.RouteGuide
可用 describe
指令查詢 server-new 提供服務的介面:
$ grpcurl -plaintext 127.0.0.1:20000 describe
grpc.reflection.v1alpha.ServerReflection is a service:
service ServerReflection {
rpc ServerReflectionInfo ( stream .grpc.reflection.v1alpha.ServerReflectionRequest ) returns ( stream .grpc.reflection.v1alpha.ServerReflectionResponse );
routeguide.RouteGuide is a service:
service RouteGuide {
rpc GetFeature ( .routeguide.Point ) returns ( .routeguide.Feature );
rpc ListFeatures ( .routeguide.Rectangle ) returns ( stream .routeguide.Feature );
rpc RecordRoute ( stream .routeguide.Point ) returns ( .routeguide.RouteSummary );
rpc RouteChat ( stream .routeguide.RouteNote ) returns ( stream .routeguide.RouteNote );
可用 describe
指令進一步查詢某參數的具體格式:
$ grpcurl -plaintext 127.0.0.1:20000 describe .routeguide.Point
routeguide.Point is a message:
message Point {
int32 latitude = 1;
int32 longitude = 2;
可看出,gRPCurl 不需要 proto 檔案,就能直接向 server-new 查詢遠端呼叫所需知道的介面細節。
最後,讓我們將含有 100 筆資料的 testdata.dat
餵給 gRPCurl 來測測看:
$ grpcurl -plaintext -d '@' \
127.0.0.1:20000 \
routeguide.RouteGuide.RecordRoute \
< testdata.dat
"pointCount": 100,
"distance": 1003784333
有了 server reflection 功能,是不是方便多了?如果你有權修改原始程式,這是值得好好考慮的,可讓測試工作輕鬆一點。
當然啦,你可以考慮在 production 環境關掉這功能;但在測試環境中,這真的很方便。
儘管 server reflection 通常不會在 production 環境啟用,不過我還是很好奇:server reflection 對執行效率的影響有多少?尤其是涉及 marshalling。
用 ghz 試試看吧!
$ ghz --insecure --data=@ -z 20s \
--call routeguide.RouteGuide.RecordRoute \
127.0.0.1:20000 \
< testdata.json
壓測 20 秒,結果如下:
Response time histogram:
0.118 [1] |
2.085 [776730] |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎
4.052 [45892] |∎∎
6.019 [3018] |
7.986 [550] |
9.953 [112] |
11.920 [74] |
13.887 [51] |
15.854 [37] |
17.821 [17] |
19.788 [1] |
Latency distribution:
10 % in 0.62 ms
25 % in 0.82 ms
50 % in 1.06 ms
75 % in 1.36 ms
90 % in 1.80 ms
95 % in 2.20 ms
99 % in 3.38 ms
Status code distribution:
[OK] 826483 responses
[Canceled] 40 responses
[Unavailable] 1 responses
Error distribution:
[40] rpc error: code = Canceled desc = grpc: the client connection is closing
[1] rpc error: code = Unavailable desc = transport is closing
雖然這還不算非常嚴謹的實驗,但可看出,沒有 server reflection 功能的 server 版本,與有此功能的 server-new 版本,執行效率沒有顯著差異。
因此,server reflection 功能,值得嘗試。
本篇文章,介紹兩個好用的 gRPC 測試小工具:輸入輸出介面測試工具 gRPCurl,以及壓測工具 ghz。最後並推薦 server reflection 功能來簡化 gRPC 測試工作。
ghz 也有 web 介面,目前是 beta 狀態。有興趣的,請去 ghz 官網看看。