gRPC是一个现代的、跨平台的、高性能的 RPC 框架。gRPC for .NET 构建在 ASP.NET Core 之上,是我们推荐的在 .NET 中构建 RPC 服务的方法。

.NET 6 进一步提高了 gRPC 已经非常出色的性能,并添加了一系列新功能,使 gRPC 在现代云原生应用程序中比以往任何时候都更好。在这篇文章中,我将描述这些新功能, 以及我们如何通过第一个支持端到端 HTTP/3 的 gRPC 实现引领行业。

gRPC 客户端负载均衡

客户端负载均衡功能允许 gRPC 客户端以最佳方式在可用服务器之间分配负载, 这样就不需要使用专门的负载均衡代理服务器, 这有几个好处:

  • 性能改进, 无代理可以减少网络延迟, 因为 RPC 直接发送到 gRPC 服务器, 无需中转。

  • 节省服务器资源,负载平衡代理必须解析然后重新发送每个 HTTP 请求, 本身也会占用 CPU 和内存, 所以移除代理可以节省服务器资源。

  • 更简单的程序架构, gRPC 负载均衡代理需要安装, 配置才能正常工作, 而使用客户端负载均衡, 客户端直接发送到服务端, 程序的架构也很简单。

如果要使用客户端负载均衡, 需要在创建 channel 的时候进行配置, 另外使用负载均衡时要考虑两个组件

  • resolver 解析器, 它可以从创建的 channel 中返回服务地址, 并且支持从外部源获取地址, 其实这就是我们熟悉的服务发现。

  • load balancer 负载均衡器, 当调用 gRPC 的时候, 它会根据配置的负载均衡的策略, 返回响应的服务地址, 并创建连接。

下面的代码中, 给 GrpcChannel 配置了 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)
{
// 这里记录错误并重试
}

在您的程序中, 你可能需要在很多地方写这样的处理代码, 幸运的是,.NET gRPC 客户端现在内置了对自动重试的支持, 只需要在 channel 上统一配置即可, 并且支持几种不同的重试策略。

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 }
}
}; // 发生错误时可以自动重试
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的序列化, 包括 Span<T>, ReadOnlySequence<T>, IBufferWriter<T> , 在.NET 6, 序列化的性能得到进一步的优化和提升。

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();
}
Method Google.Protobuf Mean Ratio Allocated
WriteString 3.14 8.838 us 1.00 0 B
WriteString 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 用户反映有时下载速度会变慢, 特别时较大的文件, 我们的调查发现,当内容大于初始的接收窗口大小时,并且客户端和服务器之间存在高延迟, 会导致网络阻塞和整体吞吐量降低。

这已在 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());
Method Runtime Mean Ratio
GrpcLargeDownload .NET 5.0 6.33 s 1.00
GrpcLargeDownload .NET 6.0 1.65 s 0.26

HTTP/3 支持

.NET 上的 gRPC 现在支持 HTTP/3, 其中在 .NET 6 的 ASP.NET Core 和 HttpClient, 有关更多信息,请参阅 .NET 6 中的 HTTP/3 支持

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

总结

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

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

我们期待听到有关使用 gRPC 和 .NET 构建的应用程序以及您未来在dotnet和grpc 存储库中的贡献!

作者: James Newton-King (.NET 首席软件工程师)

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

「译」 .NET 6 中 gRPC 的新功能的更多相关文章

  1. 「译」forEach循环中你不知道的3件事

    前言 本文925字,阅读大约需要7分钟. 总括: forEach循环中你不知道的3件事. 原文地址:3 things you didn't know about the forEach loop in ...

  2. 「译」JUnit 5 系列:条件测试

    原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...

  3. 「译」JUnit 5 系列:扩展模型(Extension Model)

    原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...

  4. 「译」JavaScript 的怪癖 1:隐式类型转换

    原文:JavaScript quirk 1: implicit conversion of values 译文:「译」JavaScript 的怪癖 1:隐式类型转换 译者:justjavac 零:提要 ...

  5. jvm系列(十):如何优化Java GC「译」

    本文由CrowHawk翻译,是Java GC调优的经典佳作. 本文翻译自Sangmin Lee发表在Cubrid上的"Become a Java GC Expert"系列文章的第三 ...

  6. jvm系列(七):如何优化Java GC「译」

    本文由CrowHawk翻译,地址:如何优化Java GC「译」,是Java GC调优的经典佳作. Sangmin Lee发表在Cubrid上的”Become a Java GC Expert”系列文章 ...

  7. iOS 9,为前端世界都带来了些什么?「译」 - 高棋的博客

    2015 年 9 月,Apple 重磅发布了全新的 iPhone 6s/6s Plus.iPad Pro 与全新的操作系统 watchOS 2 与 tvOS 9(是的,这货居然是第 9 版),加上已经 ...

  8. [译] OpenStack Kilo 版本中 Neutron 的新变化

    OpenStack Kilo 版本,OpenStack 这个开源项目的第11个版本,已经于2015年4月正式发布了.现在是个合适的时间来看看这个版本中Neutron到底发生了哪些变化了,以及引入了哪些 ...

  9. 「译」用 Blazor WebAssembly 实现微前端

    原文作者: Wael Kdouh 原文链接:https://medium.com/@waelkdouh/microfrontends-with-blazor-webassembly-b25e4ba3f ...

随机推荐

  1. 最大连续数列和 牛客网 程序员面试金典 C++ Python

    最大连续数列和 牛客网 程序员面试金典 C++ Python 题目描述 对于一个有正有负的整数数组,请找出总和最大的连续数列. 给定一个int数组A和数组大小n,请返回最大的连续数列的和.保证n的大小 ...

  2. cf18B Platforms(仔细谨慎题)

    题意: In one one-dimensional world there are n platforms. Platform with index k (platforms are numbere ...

  3. 负载均衡算法WRR介绍

    一.负载均衡 负载均衡是一个很大的概念,既有从硬件层面来解决问题的,又有从软件层面解决的,有关负载均衡的介绍,推荐阅读: http://os.51cto.com/art/201108/285359.h ...

  4. mysql查询报错this is incompatible with sql_mode=only_full_group_by

    临时改法:select @@GLOBAL.sql_mode;查询当前mysql的模式去掉ONLY_FULL_GROUP_BY重新设置:set @@GLOBAL.sql_mode='STRICT_TRA ...

  5. 在Jenkins中执行 PowerShell 命令实现高效的CD/CI部署

    相比于cmd,powershell支持插件.语法扩展和自定义扩展名,是智能化部署中闪闪的新星,越来越多的开发者偏爱使用Powershell. 如何让Jenkins支持Powershell呢?本文即展开 ...

  6. [atARC099F]Eating Symbols Hard

    记操作序列为$S$,令$h(S)\equiv \sum_{i}a_{i}x^{i}(mod\ p)$(其中$a_{i}$为操作后的结果) (以下我们将$S$看作字符串,相邻即拼接操作) 对于操作,有$ ...

  7. [nowcoder5667K]Keyboard Free

    不妨设$r1\le r2\le r3$,令$f(\alpha)=E(S_{\Delta}ABC)$,其中AB坐标分别为$(r_{1},0)$和$(r_{2}\cos \alpha,r_{2}\sin ...

  8. 小程序嵌套H5的方式和技巧(二)

    文章接上文,小程序嵌套H5的方式和技巧(一) 四.刷新wev-view嵌套的H5页面 1)我们为什么要刷新wev-view嵌套的H5页面? 很多的业务场景都需要开发者每次打开页面都更新一下页面的数据. ...

  9. 测试平台系列(81) 编写在线执行Redis功能

    大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们牛刀小试,编写了 ...

  10. C/C++ Qt TreeWidget 嵌套节点操作技巧

    在上一篇博文<C/C++ Qt TreeWidget 单层树形组件应用>中给大家演示了如何使用TreeWidget组件创建单层树形结构,并给这个树形组件增加了右键菜单功能,接下来将继续延申 ...