Go gRPC 客户端连接范围和池

问题描述 投票:0回答:2

考虑 Go gRPC 代码库中的示例:

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
) 应该是什么?我认为它应该与消费者服务处理的请求范围有密切关系,但我还没有找到与此相关的任何文档。我应该在这里使用连接池吗?

EG

  1. gRPC消费者服务接收请求
  2. 建立与 gRPC 服务的连接(直接或通过池)
  3. 向 gRPC 服务发出 n 请求
  4. 关闭 gRPC 连接(或释放回池)
go grpc
2个回答
15
投票

根据经验,gRPC 客户端连接应在客户端应用程序的生命周期内重复使用,因为它们可以安全地并发使用。此外,gRPC 的关键功能之一是远程过程调用的快速响应,如果您必须在收到每个请求时重新连接,则无法实现这一点。

尽管如此,强烈建议将某种 gRPC 负载平衡与这些持久连接一起使用。否则,大量负载可能最终会落在一些长期存在的 grpc 客户端-服务器连接上。负载平衡选项包括:

  1. 客户端的 gRPC 连接池与服务器端 TCP(第 4 层)负载均衡器相结合。这将首先创建一个客户端连接池,并为后续的 gRPC 请求重新使用该连接池。我认为这是更容易实施的途径。有关 grpc 客户端上使用 grpc-go-pool 库的 grpc 连接池示例,请参阅池化 gRPC 连接
  2. HTTP/2(第 7 层)负载均衡器,支持负载均衡请求的 gRPC。请参阅 gRPC 负载平衡,其中概述了不同的 grpc 负载平衡选项。 nginx 最近添加了对 gRPC 负载均衡的支持

0
投票

我在为超大规模系统(300K RPS)实施 gRPC 时在我的组织中遇到了类似的问题,并偶然发现了这篇文章。

实现客户端和服务器之间的负载平衡似乎是一个挑战,有许多新发现。我们探索了许多可用的开源解决方案,但它们有一个或另一个缺点,不适合我们的用例。

我记录了我们如何解决所有问题以及定制解决方案如何帮助我们解决所有问题的整个过程。

中型文章:- https://arpittech.medium.com/grpc-and-connection-pooling-49a4137095e7

我将这篇文章发布在这里,供遇到类似问题的任何人以及我们如何解决所有这些问题。这只是回馈社区的一种方式。

附注-> 感谢所有对此问题的答复。它帮助我带来了 初步了解了:)

© www.soinside.com 2019 - 2024. All rights reserved.