gRPC是一个现代的、跨平台的、高性能的 RPC 框架。gRPC for .NET 构建在 ASP.NET Core 之上,是我们推荐的使用 .NET 构建 RPC 服务的方法。
.NET 6 进一步提高了 gRPC 已经非常出色的性能,并添加了一系列新功能,使 gRPC 在现代云原生应用程序中比以往任何时候都更好。在这篇文章中,我将描述这些新功能以及我们如何通过第一个支持端到端 HTTP/3 的 gRPC 实现引领行业。
gRPC 客户端负载均衡
客户端负载平衡是一项允许 gRPC 客户端在可用服务器之间优化分配负载的功能。客户端负载平衡可以消除对负载平衡代理的需要。这有几个好处:
- 改进的性能。无代理意味着消除额外的网络跃点并减少延迟,因为 RPC 直接发送到 gRPC 服务器。
- 有效利用服务器资源。负载平衡代理必须解析然后重新发送通过它发送的每个 HTTP 请求。删除代理可以节省 CPU 和内存资源。
- 更简单的应用程序架构。必须正确设置和配置代理服务器。没有代理服务器意味着更少的活动部件!
客户端负载均衡是在创建通道时配置的。使用负载均衡时要考虑的两个组件:
- 解析器,解析通道的地址。解析器支持从外部源获取地址。这也称为服务发现。
- 负载均衡器,它创建连接并选择 gRPC 调用将使用的地址。
以下代码示例将通道配置为使用具有循环负载平衡的 DNS 服务发现:
var channel = GrpcChannel.ForAddress(
"dns:///my-example-host",
new GrpcChannelOptions
{
Credentials = ChannelCredentials.Insecure,
ServiceConfig = new ServiceConfig { LoadBalancingConfigs = { new RoundRobinConfig() } }
});
var client = new Greet.GreeterClient(channel);
var response = await client.SayHelloAsync(new HelloRequest { Name = "world" });
有关更多信息,请参阅gRPC 客户端负载平衡。
带有重试的瞬时故障处理
gRPC 调用可能会被瞬时故障中断。瞬态故障包括:
- 网络连接暂时中断。
- 服务暂时不可用。
- 由于服务器负载超时。
当 gRPC 调用中断时,客户端会抛出RpcException
有关错误的详细信息。客户端应用程序必须捕获异常并选择如何处理错误。
var client = new Greeter.GreeterClient(channel);
try
{
var response = await client.SayHelloAsync(
new HelloRequest { Name = ".NET" });
Console.WriteLine("From server: " + response.Message);
}
catch (RpcException ex)
{
// Write logic to inspect the error and retry
// if the error is from a transient fault.
}
在整个应用程序中复制重试逻辑是冗长且容易出错的。幸运的是,.NET gRPC 客户端现在内置了对自动重试的支持。重试在通道上集中配置,并且有许多选项可用于使用RetryPolicy
.
var defaultMethodConfig = new MethodConfig
{
Names = { MethodName.Default },
RetryPolicy = new RetryPolicy
{
MaxAttempts = 5,
InitialBackoff = TimeSpan.FromSeconds(1),
MaxBackoff = TimeSpan.FromSeconds(5),
BackoffMultiplier = 1.5,
RetryableStatusCodes = { StatusCode.Unavailable }
}
};
// Clients created with this channel will automatically retry failed calls.
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
{
ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }