「译」 .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 负载均衡代理需要安装, 配置才能正常工作, 而使用客户端负载均衡, 客户端直接发送到服务端, 程序的架构也很简单。
如果要使用客户端负载均衡, 需要在创建 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 的新功能的更多相关文章
- 「译」forEach循环中你不知道的3件事
前言 本文925字,阅读大约需要7分钟. 总括: forEach循环中你不知道的3件事. 原文地址:3 things you didn't know about the forEach loop in ...
- 「译」JUnit 5 系列:条件测试
原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...
- 「译」JUnit 5 系列:扩展模型(Extension Model)
原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...
- 「译」JavaScript 的怪癖 1:隐式类型转换
原文:JavaScript quirk 1: implicit conversion of values 译文:「译」JavaScript 的怪癖 1:隐式类型转换 译者:justjavac 零:提要 ...
- jvm系列(十):如何优化Java GC「译」
本文由CrowHawk翻译,是Java GC调优的经典佳作. 本文翻译自Sangmin Lee发表在Cubrid上的"Become a Java GC Expert"系列文章的第三 ...
- jvm系列(七):如何优化Java GC「译」
本文由CrowHawk翻译,地址:如何优化Java GC「译」,是Java GC调优的经典佳作. Sangmin Lee发表在Cubrid上的”Become a Java GC Expert”系列文章 ...
- iOS 9,为前端世界都带来了些什么?「译」 - 高棋的博客
2015 年 9 月,Apple 重磅发布了全新的 iPhone 6s/6s Plus.iPad Pro 与全新的操作系统 watchOS 2 与 tvOS 9(是的,这货居然是第 9 版),加上已经 ...
- [译] OpenStack Kilo 版本中 Neutron 的新变化
OpenStack Kilo 版本,OpenStack 这个开源项目的第11个版本,已经于2015年4月正式发布了.现在是个合适的时间来看看这个版本中Neutron到底发生了哪些变化了,以及引入了哪些 ...
- 「译」用 Blazor WebAssembly 实现微前端
原文作者: Wael Kdouh 原文链接:https://medium.com/@waelkdouh/microfrontends-with-blazor-webassembly-b25e4ba3f ...
随机推荐
- cf14D Two Paths(树的直径)
题意: N个点构成一棵树.树枝的长度都是1. 在当中找两条不相交[没有公共点]的路,使得二者长度之积最大. (2 ≤ n ≤ 200) 思路: 一开始思路好麻烦,好麻烦,好麻烦,,,,,,,而且WA, ...
- Python小练习之验证“哥德巴赫猜想”
设计内容:任何一个大于2的偶数都可以分解为两个素数之和,这就是著名的哥达巴赫猜想. 设计要求:要求输入一个大于2的偶数,程序运行后,输出两个素数,其和正好等于该偶数. 1. 实验代码(知道是你们 ...
- 力扣 - 剑指 Offer 67. 把字符串转换成整数
题目 剑指 Offer 67. 把字符串转换成整数 思路1 根据题意,要解决这题,首先要判断的条件有: 不包括首位空格 第一位必须为:+.-.数字三者其一,否则不合法 数字必须连续的,如果遇到非数字, ...
- 大数据中必须要掌握的 Flink SQL 详细剖析
Flink SQL 是 Flink 实时计算为简化计算模型,降低用户使用实时计算门槛而设计的一套符合标准 SQL 语义的开发语言. 自 2015 年开始,阿里巴巴开始调研开源流计算引擎,最终决定基于 ...
- 【Python+postman接口自动化测试】(3)什么是接口测试?
什么是接口测试? 接口测试是测试系统组件间接口的一种测试.接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点.测试的重点是要检查数据的交换.传递和控制管理过程,以及系统间的相互逻辑依 ...
- Oracle四大语言DDL DML DCL TCL
DDL(数据定义语言) creater 创建数据表 ceater table 表名 (); alter 修改表结构 添加字段:alter table 表名 add 列名 数据类型 null 删除字段: ...
- 问题 L: Yougth的最大化
题目描述 Yougth现在有n个物品的重量和价值分别是Wi和Vi,你能帮他从中选出k个物品使得单位重量的价值最大吗? 输入 有多组测试数据 每组测试数据第一行有两个数n和k,接下来一行有n个数Wi和V ...
- CentOS 设置网络及安装 ifconfig
centos使用yum报错"Could not resolve host: mirrorlist.centos.org; 未知的错误" 先用NetworkManager包的nmcl ...
- <C#任务导引教程>练习二
//6,goto语句求1+++100之和using System;class Program{ static void Main() { int i=1,sum=0; ...
- [bzoj1677]求和
dp,用f[i]表示i划分的方案,直接枚举最后一个数是错误的,因为会导致c重复计数,然后正解十分神奇--当i为奇数,那么分解中一定有1,因此f[i]=f[i-1]当i为偶数若有1,同样转移到f[i-1 ...