web-dev-qa-db-ja.com

gRPCクライアント接続スコープとプーリングに移動します

GogRPCコードベースの例を考えてみましょう。

func main() {
    // Set up a connection to the server.
    conn, err := grpc.Dial(address, grpc.WithInsecure())
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()
    c := pb.NewGreeterClient(conn)

    // Contact the server and print out its response.
    name := defaultName
    if len(os.Args) > 1 {
        name = os.Args[1]
    }
    r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name})
    if err != nil {
        log.Fatalf("could not greet: %v", err)
    }
    log.Printf("Greeting: %s", r.Message)
}

別のサービスからgRPCサービスを利用する場合、接続のスコープ(conn)はどのようにすべきですか?処理されるリクエストの範囲がコンシューマーサービスであることに親和性があるはずですが、これに関するドキュメントはまだ見つかりません。ここで接続プールを使用する必要がありますか?

例えば。

  1. gRPCコンシューマーサービスがリクエストを受信
  2. gRPCサービスへの接続を確立する(直接またはプール経由で)
  3. make n gRPCサービスへのリクエスト
  4. gRPC接続を閉じます(またはプールに解放します)
6
Myles McDonnell

経験上、gRPCクライアント接続は、同時使用しても安全であるため、クライアントアプリケーションの存続期間中は再利用する必要があります。さらに、gRPCの重要な機能の1つは、リモートの手続き型呼び出しからの迅速な応答です。これは、受信したすべての要求で再接続する必要がある場合には実現されません。

それでも、これらの持続的接続とともに、ある種のgRPCロードバランシングを使用することを強くお勧めします。そうしないと、負荷の多くが、いくつかの長寿命のgrpcクライアントサーバー接続で発生する可能性があります。負荷分散オプションには次のものがあります。

  1. サーバー側と組み合わせたクライアント側のgRPC接続プールTCP(レイヤー4)ロードバランサー。これにより、最初にクライアント接続のプールが作成され、この接続プールが後続のgRPCで再利用されます。これは私の意見では実装するのが簡単なルートです。 grpc-go-pool を使用するgrpcクライアント側でのgrpc接続プールの例については gRPC接続のプール を参照してください。図書館。
  2. 負荷分散リクエストをgRPCでサポートするHTTP/2(レイヤー7)ロードバランサー。 gRPCロードバランシング を参照してください。これは、さまざまなgrpcロードバランシングオプションの概要を示しています。 nginx最近 gRPCロードバランシングのサポートが追加されました
6
Agrim