在 .NET 依赖注入中,gRPC 通道应该是单例通道、作用域通道还是瞬态通道?

Kei*_*ith 5 dependency-injection grpc .net-5 grpc-dotnet asp.net-core-3.1

.NET 中的 gRPC 请求依赖于通道,必须关闭并处置该通道:

using var channel = Grpc.Net.Client.GrpcChannel.ForAddress("path to service");

//...do stuff...

await channel.ShutdownAsync();
Run Code Online (Sandbox Code Playgroud)

我正在使用 .NET 依赖注入服务将其包装起来IServiceCollection,这应该是......

  • 每个方法 - 在每个方法调用内创建和处置通道。
  • AddTransient- 每次请求我的服务时都会有一个新频道,但仅限于需要时。
  • AddScoped- 每个请求都有一个新通道,但保持通道打开直到请求完成。
  • AddSingleton- 该应用程序的一个新频道。

认为 AddSingleton已经过时了,因为我不确定如何GrpcChannel同时处理大量并行请求,并且我想传递CancellationToken当前请求。

AddScoped这就需要在VSAddTransient与每种方法之间进行选择。如果没有大量的测试(并陷入所有陷阱),我不确定这里的最佳实践是什么(我是 gRPC 的新手)。我应该尽快关闭该通道,还是保持其打开并在通话之间共享?

小智 5

根据微软 https://learn.microsoft.com/en-us/aspnet/core/grpc/client?view=aspnetcore-5.0#client-performance

通道代表与 gRPC 服务的长期连接。

渠道和客户端性能和使用情况:

  • 创建通道可能是一项昂贵的操作。重用 gRPC 调用通道可带来性能优势。
  • gRPC 客户端是使用通道创建的。gRPC 客户端是轻量级对象,不需要缓存或重用。
  • 一个通道可以创建多个gRPC客户端,包括不同类型的客户端。
  • 通道和从通道创建的客户端可以安全地由多个线程使用。
  • 从通道创建的客户端可以同时进行多个呼叫。需要缓存或重用。一个通道可以创建多个gRPC客户端,包括不同类型的客户端。通道和从通道创建的客户端可以安全地由多个线程使用。从通道创建的客户端可以同时进行多个呼叫。

根据 grpc https://grpc.github.io/grpc/csharp-dotnet/api/Grpc.Net.Client.GrpcChannel.html

类 GrpcChannel 表示 gRPC 通道。通道是与远程服务器的长期连接的抽象。客户端对象可以重用相同的通道。与调用远程调用相比,创建通道是一项昂贵的操作,因此通常您应该为尽可能多的调用重复使用单个通道。

与往常一样,这取决于您想要做什么,但单例可能只应创建单个通道。另外,如果您确实需要处理较重的负载,请尝试使用SocketsHttpHandler.EnableMultipleHttp2Connectionshttps://learn.microsoft.com/en-us/aspnet/core/grpc/performance?view=aspnetcore-5.0#connection-concurrency