.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 客戶端負載平衡[1]。
瞬時故障的處理和重試
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 重試進行瞬態故障處理[2]。
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[3]?支持了矢量化字符串的序列化。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[4]?添加了一個用于創建?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[5]?中修復。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 支持[6]。
.NET 是第一個支持端到端 HTTP/3 的 gRPC 實現,我們已經為其他平臺提交了?gRFC[7],以便將來支持 HTTP/3。帶有 HTTP/3 的 gRPC 是開發人員社區高度要求的功能[8],很高興看到 .NET 在該領域處于領先地位。
總結
性能是 .NET 和 gRPC 的一個重要特性,而 .NET 6 比以往任何時候都快。客戶端負載均衡和 HTTP/3 等以性能為導向的新功能意味著更低的延遲、更高的吞吐量和更少的服務器。這是一個節省資金、減少能耗和構建更環保的云原生應用程序的機會。
要試用新功能并開始在 .NET 中使用 gRPC,最好的起點是在 ASP.NET Core教程中?創建 gRPC 客戶端和服務器[9]。
我們期待聽到有關使用 gRPC 和 .NET 構建的應用程序以及您未來在dotnet和grpc 存儲庫中的貢獻!
作者: James Newton-King?
原文: https://devblogs.microsoft.com/dotnet/grpc-in-dotnet-6/
相關鏈接
[1]?gRPC 客戶端負載平衡:?https://docs.microsoft.com/zh-cn/aspnet/core/grpc/loadbalancing?view=aspnetcore-6.0
[2]?gRPC 重試進行瞬態故障處理:?https://docs.microsoft.com/zh-cn/aspnet/core/grpc/retries?view=aspnetcore-6.0
[3]?protocolbuffers/protobuf#8147:?https://github.com/protocolbuffers/protobuf/pull/8147
[4]?protocolbuffers/protobuf#7645:?https://github.com/protocolbuffers/protobuf/pull/7645
[5]?dotnet/runtime#54755:?https://github.com/protocolbuffers/protobuf/pull/7645
[6]?.NET 6 中的 HTTP/3 支持:?https://devblogs.microsoft.com/dotnet/http-3-support-in-dotnet-6/
[7]?gRFC:?https://github.com/grpc/proposal/pull/256
[8]?開發人員社區高度要求的功能:?https://github.com/grpc/grpc/issues/19126
[9]?創建 gRPC 客戶端和服務器:?https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/grpc/grpc-start?view=aspnetcore-6.0&tabs=visual-studio
總結
以上是生活随笔為你收集整理的.NET 6 中 gRPC 的新功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSharp 如何OCR离线识别文本
- 下一篇: 使用C#为MSTest测试项目实现自定义