GRPC 客户端阻塞与异步存根建议

pra*_*ank 6 grpc grpc-java

我们目前正在使用 grpc-starter 包https://github.com/yidongnan/grpc-spring-boot-starter实现高吞吐量的 Spring Boot 应用程序,这是一个基于客户端服务器的应用程序。我们正在将旧的 REST 端点 CRUD 操作迁移到 GRPC。为了获得这项服务的最佳设计,我们需要帮助解决以下问题:

  1. 如果单个不可变 GRPC 阻塞存根客户端实例被多个线程访问,这将是阻塞调用,即在任何给定时间仅执行一个 RPC 调用。

  2. 根据 google GRPC IO 文档,建议不要使用阻塞存根来并行化 RPC 调用。这是否突出显示了同一客户端对象上的多个 RPC 调用的情况。https://grpc.io/docs/guides/performance/

  3. 阻塞存根是否会为每个调用使用新的 TCP 连接,或者重复使用相同的 TCP 连接。

Eri*_*son 4

如果单个不可变 GRPC 阻塞存根客户端实例被多个线程访问,这将是阻塞调用,即在任何给定时间仅执行一个 RPC 调用。

不,RPC 将并行进行。存根是通道周围的薄包装,通道将同时执行多个 RPC。

根据 google GRPC IO 文档,建议不要使用阻塞存根来并行化 RPC 调用。

这是因为阻塞是一个扩展问题。每个阻塞 RPC 都会消耗一个线程,而 Java 中的线程非常大(~1 MB)。异步还可以减少大规模的上下文切换开销。gRPC Java 对于阻塞和异步来说同样有效。

请注意,这通常意味着您可以使用阻塞,而不必担心任何小规模 RPC。您可以选择仅在同时具有许多(100+)未完成的 RPC 上使用异步或未来存根。

阻塞存根是否会为每个调用使用新的 TCP 连接,或者重复使用相同的 TCP 连接。

TCP 连接将被重用。gRPC Java 对阻塞和异步使用相同的 Channel API。所以唯一的区别是您看到的 API。

  • 由于阻塞调用是通过使用现有线程调用方法来启动的,因此这意味着您的并发度_不能_高于线程数。因此,如果您想在不增加线程数量的情况下增加并发性,那么是的,您应该使用异步或基于未来的存根来增加并发性。 (2认同)