私は 2 つのサービス A と B を実装しました。A は gRPC (Mali で grpc-node を使用) と純粋な HTTP REST 呼び出しの両方を介して B と通信できます。
リクエストのサイズは無視できます。
応答サイズは、次のような 1000 アイテムです。
{
"productId": "product-0",
"description": "some-text",
"price": {
"currency": "GBP",
"value": "12.99"
},
"createdAt": "2020-07-12T18:03:46.443Z"
}
A と B の両方がサービスとして GKE にデプロイされ、kube-proxy を使用して内部ネットワーク経由で通信します。
私が発見したのは、REST バージョンが gRPC よりもはるかに高速であることです。REST 呼び出しの p99 は 1 秒未満であり、gRPC の p99 は 30 秒を超えることがあります。
詳細
ノードのバージョンと OS:node:14.7.0-alpine3.12
依存関係:
"google-protobuf": "^3.12.4",
"grpc": "^1.24.3",
"mali": "^0.21.0",
gRPC オプションを設定してクライアント側の TCP プーリングを作成しましgrpc.use_local_subchannel_pool=1
たが、これは役に立たないようです。
call.startBatch
grpc libの呼び出しがサイズ〜51kbのデータを送信するのに何秒もかかったことがログからわかるように、問題はサーバー側にあるようです。これは REST バージョンよりもかなり遅いです。
また、サービスの CPU とネットワークが正常であることも確認しました。REST バージョンは 2 mbps を超える速度で送信できましたが、gRPC バージョンは最大 150 kbps しか管理できませんでした。
netstat
サービス B で (gRPC で)実行すると、多くの ESTABLISHED TCP 接続が表示されます (TCP プーリングのために予想どおり)。
私の疑いは、grpc-core C++ コードが REST より最適ではないということですが、証拠はありません。
次に見るべきアイデアはありますか?助けてくれてありがとう
更新 1
いくつかのベンチマークを次に示します。
設定
Blazemeter --REST--> services A --gRPC/REST--> service B
- リクエストボディ(両方のラグ)は無視できます
service A
はノードサービス + Koaservice B
3 つのオプションがあります。grpc-node
: grpc-node を持つノードgRPC + Go
: 同じ gRPC サービスの Go 実装REST + Koa
: Koa のあるノード
Blazemeter --> service A
: 応答ペイロードは無視でき、すべてのテストで同じですserivce A --> service B
: gRPC/REST 応答ペイロードは 1000 個ですProductPrice
:
message ProductPrice {
string product_id = 1; // Hard coded to "product-x", x in [0 ... 999]
string description = 2; // Hard coded to random string, length = 10
Money price = 3;
google.protobuf.Timestamp created_at = 4; // Hard coded
}
message Money {
Currency currency = 1; // Hard coded to GBP
string value = 2; // Hard coded to "12.99"
}
enum Currency {
CURRENCY_UNKNOWN = 0;
GBP = 1;
}
サービスは GCP の Kubernetes にデプロイされ、
- インスタンスタイプ:
n1-highcpu-4
- サービスごとに 5 つのポッド
- 各ポッドに 2 つの CPU、1 GB のメモリ
- クラスター IP を使用する kube-proxy (インターネット経由ではない) (ヘッドレスを
clusterIP: None
でテストしたところ、同様の結果が得られました)
ロード
50rps
結果
grpc-node を使用したサービス B
Go gRPC を使用したサービス B
Koa で REST を使用するサービス B
ネットワーク IO
観察
gRPC + Go
とほぼ同等ですREST
(gRPCの方が速いと思いました)grpc-node
よりも 4 倍遅いREST
- ネットワークがボトルネックではない