• (摘).NET 6 中 gRPC 的新功能


    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 } }
    });

    有关更多信息,请参阅使用 gRPC 重试进行瞬态故障处理

    Protobuf 性能

    gRPC for .NET 使用 Google.Protobuf 包作为消息的默认序列化程序。Protobuf 是一种高效的二进制序列化格式。Google.Protobuf 旨在提高性能,使用代码生成而不是反射来序列化 .NET 对象。在.NET 5,我们用的Protobuf团队合作以增加对现代内存的API,如支持以及对串行器。.NET 6 中的改进优化了一个已经很快的序列化程序。Span<T>ReadOnlySequence<T>IBufferWriter<T>

    protocolbuffers/protobuf#8147添加了矢量化字符串序列化。SIMD 指令允许并行处理多个字符,从而在序列化某些字符串值时显着提高性能。

    private string _value = new string(' ', 10080);
    private byte[] _outputBuffer = new byte[10080];
    
    [Benchmark]
    public void WriteString()
    {
        var span = new Span<byte>(_outputBuffer);
        WriteContext.Initialize(ref span, out WriteContext ctx);
        ctx.WriteString(_value);
        ctx.Flush();
    }
    方法Google.Protobuf平均比率已分配
    写字符串 3.14 8.838 us 1.00 0 B
    写字符串 3.18 2.919 ns 0.33 0 B

    protocolbuffers/protobuf#7645添加了一个用于创建ByteString实例的新 API 如果您知道底层数据不会改变,那么使用创建一个而不复制底层数据。如果应用程序处理大字节有效负载并且您想降低垃圾收集频率,这将非常有用。UnsafeByteOperations.UnsafeWrapByteString

    var data = await File.ReadAllBytesAsync(@"c:large_file.json");
    
    // Safe but slow.
    var copied = ByteString.CopyFrom(data);
    
    // Unsafe but fast. Useful if you know data won't change.
    var wrapped = UnsafeByteOperations.UnsafeWrap(data);

    gRPC 下载速度

    gRPC 用户报告有时下载速度变慢。我们的调查发现,当客户端和服务器之间存在延迟时,HTTP/2 流量控制会限制下载。服务器在客户端可以耗尽之前填充接收缓冲区窗口,导致服务器暂停发送数据。gRPC 消息以开始/停止突发方式下载。

    这已在dotnet/runtime#54755 中修复HttpClient现在动态缩放接收缓冲区窗口。建立 HTTP/2 连接后,客户端将向服务器发送 ping 以测量延迟。如果存在高延迟,客户端会自动增加接收缓冲区窗口,从而实现快速、连续的下载。

    private GrpcChannel _channel = GrpcChannel.ForAddress(...);
    private DownloadClient _client = new DownloadClient(_channel);
    
    [Benchmark]
    public Task GrpcLargeDownload() =>
        _client.DownloadLargeMessageAsync(new EmptyMessage());
    方法运行用时比率
    GrpcLarge下载 .NET 5.0 6.33 秒 1.00
    GrpcLarge下载 .NET 6.0 1.65 秒 0.26

    HTTP/3 支持

    .NET 上的 gRPC 现在支持 HTTP/3。gRPC 构建在添加到 ASP.NET Core 和HttpClient.NET 6 中的 HTTP/3 支持之上。有关更多信息,请参阅.NET 6 中的 HTTP/3 支持

    .NET 是第一个支持端到端 HTTP/3 的 gRPC 实现,我们已经为其他平台提交了 gRFC,以便将来支持 HTTP/3。带有 HTTP/3 的 gRPC 是开发人员社区高度要求的功能,高兴看到 .NET 在该领域处于领先地位。

    gRPC 和 HTTP/3

    总结

    性能是 .NET 和 gRPC 的一个特性,而 .NET 6 比以往任何时候都快。客户端负载平衡和 HTTP/3 等以性能为导向的新功能意味着更低的延迟、更高的吞吐量和更少的服务器。这是一个节省资金、减少能耗和构建更环保的云原生应用程序的机会。

    要试用新功能并开始在 .NET 中使用 gRPC,最好的起点是在 ASP.NET Core教程中创建 gRPC 客户端和服务器

    原文地址:https://devblogs.microsoft.com/dotnet/grpc-in-dotnet-6/

  • 相关阅读:
    【bzoj1191】 HNOI2006—超级英雄Hero
    【poj3020】 Antenna Placement
    【poj1274】 The Perfect Stall
    【poj2724】 Purifying Machine
    【poj2226】 Muddy Fields
    【codevs1257】 打砖块
    【poj2186】 Popular Cows
    【poj1236】 Network of Schools
    【poj1144】 Network
    【poj3177】 Redundant Paths
  • 原文地址:https://www.cnblogs.com/mlinber/p/15726600.html
Copyright © 2020-2023  润新知