浅谈.NET 6 中 gRPC 的最新功能
gRPC?是一個(gè)現(xiàn)代的、跨平臺(tái)的、高性能的 RPC 框架。gRPC 是構(gòu)建在 ASP.NET Core 之上,也是我們推薦的使用 .NET 構(gòu)建 RPC 服務(wù)的方法。
.NET 6 進(jìn)一步提高了 gRPC 已經(jīng)非常出色的性能,并添加了一系列新功能,使 gRPC 在現(xiàn)代云原生應(yīng)用程序中比以往任何時(shí)候都更好。在這篇文章中,我將描述這些新功能以及我們?nèi)绾瓮ㄟ^(guò)第一個(gè)支持端到端 HTTP/3 的 gRPC 實(shí)現(xiàn)引領(lǐng)行業(yè)。
gPRC?客戶端負(fù)載均衡
客戶端負(fù)載平衡是一項(xiàng)允許 gRPC 客戶端在可用服務(wù)器之間優(yōu)化分配負(fù)載的功能。客戶端負(fù)載平衡可以消除對(duì)負(fù)載平衡代理的需要。這有幾個(gè)好處:
改進(jìn)的性能。無(wú)代理意味著消除額外的網(wǎng)絡(luò)躍點(diǎn)并減少延遲,因?yàn)?RPC 直接發(fā)送到 gRPC 服務(wù)器。
有效利用服務(wù)器資源。負(fù)載平衡代理必須解析然后重新發(fā)送通過(guò)它發(fā)送的每個(gè) HTTP 請(qǐng)求。刪除代理可以節(jié)省 CPU 和內(nèi)存資源。
更簡(jiǎn)單的應(yīng)用程序架構(gòu)。必須正確設(shè)置和配置代理服務(wù)器。沒(méi)有代理服務(wù)器意味著更少的活動(dòng)部件!
客戶端負(fù)載均衡是在創(chuàng)建通道時(shí)配置的。使用負(fù)載均衡時(shí)要考慮的兩個(gè)組件:
解析器,解析通道的地址。解析器支持從外部源獲取地址。這也稱(chēng)為服務(wù)發(fā)現(xiàn)。
負(fù)載均衡器,它創(chuàng)建連接并選擇 gRPC 調(diào)用將使用的地址。
以下代碼示例將通道配置為使用具有循環(huán)負(fù)載平衡的 DNS 服務(wù)發(fā)現(xiàn):
var channel = GrpcChannel.ForAddress(
??? "dns:///my-example-host",
??? newGrpcChannelOptions
??? {
??????? Credentials = ChannelCredentials.Insecure,
??????? ServiceConfig = newServiceConfig { LoadBalancingConfigs = { newRoundRobinConfig() } }
??? });
var client = newGreet.GreeterClient(channel);
var response = await client.SayHelloAsync(newHelloRequest { Name = "world" });
更多信息,請(qǐng)參閱?gPRC?客戶端負(fù)載平衡。
gPRC?
https://docs.microsoft.com/aspnet/core/grpc/
gPRC 客戶端負(fù)載平衡:
https://docs.microsoft.com/aspnet/core/grpc/loadbalancing
帶有重試的瞬間故障處理
gRPC 調(diào)用可能會(huì)被瞬時(shí)故障中斷。瞬態(tài)故障包括:
網(wǎng)絡(luò)連接暫時(shí)中斷。
服務(wù)暫時(shí)不可用。
由于服務(wù)器負(fù)載超時(shí)。
當(dāng) gRPC 調(diào)用被中斷時(shí),客戶端會(huì)拋出一個(gè)包含錯(cuò)誤詳細(xì)信息的 RpcException。客戶端應(yīng)用程序必須捕獲異常并選擇如何處理錯(cuò)誤。
var client =newGreeter.GreeterClient(channel);try{var response =await client.SayHelloAsync(newHelloRequest{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.}
在整個(gè)應(yīng)用程序中復(fù)制重試邏輯是冗長(zhǎng)且容易出錯(cuò)的。幸運(yùn)的是,.NET gRPC 客戶端現(xiàn)在內(nèi)置了對(duì)自動(dòng)重試的支持。重試在通道上集中配置,并且有許多選項(xiàng)可用于使用 RetryPolicy 自定義重試行為。
var defaultMethodConfig =newMethodConfig{Names={MethodName.Default},RetryPolicy=newRetryPolicy{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",newGrpcChannelOptions{ServiceConfig=newServiceConfig{MethodConfigs={ defaultMethodConfig }}});有關(guān)更多信息,請(qǐng)參閱使用 gRPC 重試進(jìn)行瞬態(tài)故障處理。使用 gPRC 重試進(jìn)行瞬態(tài)故障處理:
https://docs.microsoft.com/aspnet/core/grpc/retries
Protobuf 性能
關(guān)于.NET 的 gRPC 使用 Google.Protobuf 包作為消息的默認(rèn)序列化程序。Protobuf 是一種高效的二進(jìn)制序列化格式。Google.Protobuf 旨在提高性能,使用代碼生成而不是反射來(lái)序列化 .NET 對(duì)象。在 .NET 5 中,我們與 Protobuf 團(tuán)隊(duì)合作,為序列化程序添加了對(duì)現(xiàn)代內(nèi)存 API(例如 Span<T>、ReadOnlySequence<T>和IBufferWriter<T>)的支持。.NET 6 中的改進(jìn)優(yōu)化了一個(gè)已經(jīng)很快的序列化程序。?
protocolbuffers/protobuf#8147添加了矢量化字符串序列化。SIMD 指令允許并行處理多個(gè)字符,從而在序列化某些字符串值時(shí)顯著提高性能。
privatestring _value =newstring(' ',10080);privatebyte[] _outputBuffer =newbyte[10080];[Benchmark]publicvoidWriteString(){var span =newSpan<byte>(_outputBuffer);WriteContext.Initialize(ref span,outWriteContext ctx);ctx.WriteString(_value);ctx.Flush();}Method? | .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添加了一個(gè)用于創(chuàng)建 ByteString 實(shí)例的新 API。如果你知道底層數(shù)據(jù)不會(huì)改變,那么使用 UnsafeByteOperations.UnsafeWrap 來(lái)創(chuàng)建一個(gè) ByteString 而不復(fù)制底層數(shù)據(jù)。如果應(yīng)用程序處理大字節(jié)有效負(fù)載并且您想降低垃圾收集頻率,這將非常有用。
protocolbuffers/protobuf#7645:
https://github.com/protocolbuffers/protobuf/pull/7645
gPRC?下載速度
gRPC 用戶報(bào)告有時(shí)下載速度變慢。我們的調(diào)查發(fā)現(xiàn),當(dāng)客戶端和服務(wù)器之間存在延遲時(shí),HTTP/2 流量控制會(huì)限制下載。服務(wù)器在客戶端可以耗盡之前填充接收緩沖區(qū)窗口,導(dǎo)致服務(wù)器暫停發(fā)送數(shù)據(jù)。gRPC 消息以開(kāi)始/停止突發(fā)方式下載。
這已在 dotnet/runtime#54755中修復(fù)。HttpClient 現(xiàn)在動(dòng)態(tài)縮放接收緩沖區(qū)窗口。建立HTTP/2 連接后,客戶端將向服務(wù)器發(fā)送 ping 以測(cè)量延遲。如果存在高延遲,客戶端會(huì)自動(dòng)增加接收緩沖區(qū)窗口,從而實(shí)現(xiàn)快速、連續(xù)的下載。
privateGrpcChannel _channel =GrpcChannel.ForAddress(...);privateDownloadClient _client =newDownloadClient(_channel);[Benchmark]publicTaskGrpcLargeDownload()=>??? _client.DownloadLargeMessageAsync(newEmptyMessage());
Method | Runtime | Mean | Ratio |
GrpcLargeDownload | .NET 5.0 | 6.33 s | 1.00 |
GrpcLargeDownload | .NET 6.0 | 1.65 s | 0.26 |
dotnet/runtime#54755
https://github.com/dotnet/runtime/pull/54755
HTTP/3?支持
NET 上的 gRPC 現(xiàn)在支持 HTTP/3。gRPC 建立在 .NET 6 中添加到 ASP.NET Core 和 HttpClient 的 HTTP/3 支持之上。有關(guān)更多信息,請(qǐng)參閱.NET 6 中的 HTTP/3支持。
.NET 是第一個(gè)支持端到端 HTTP/3 的 gRPC 實(shí)現(xiàn),我們已經(jīng)為其他平臺(tái)提交了 gRFC,以便將來(lái)支持 HTTP/3。帶有 HTTP/3 的 gRPC 是開(kāi)發(fā)人員社區(qū)高度要求的功能,很高興看到 .NET 在該領(lǐng)域處于領(lǐng)先地位。
.NET 6 中的 HTTP/3 :
https://devblogs.microsoft.com/dotnet/http-3-support-in-dotnet-6/
gRFC:
https://github.com/grpc/proposal/pull/256
開(kāi)發(fā)人員社區(qū)高度要求的功能:
https://github.com/grpc/grpc/issues/19126
總結(jié)
性能是 .NET 和 gRPC 的一個(gè)特性,而 .NET 6 比以往任何時(shí)候都快。客戶端負(fù)載平衡和 HTTP/3 等以性能為導(dǎo)向的新功能意味著更低的延遲、更高的吞吐量和更少的服務(wù)器。這是一個(gè)節(jié)省資金、減少能耗和構(gòu)建更環(huán)保的云原生應(yīng)用程序的機(jī)會(huì)。
要試用新功能并開(kāi)始在 .NET 中使用 gRPC,最好的起點(diǎn)是在 ASP.NET Core 教程中創(chuàng)建 gRPC 客戶端和服務(wù)器。
我們期待聽(tīng)到有關(guān)使用 gRPC 和 .NET 構(gòu)建的應(yīng)用程序以及您在?dotnet?和?grpc?存儲(chǔ)庫(kù)中的貢獻(xiàn)!
構(gòu)建更環(huán)保的云原生應(yīng)用程序 :
https://docs.microsoft.com/aspnet/core/tutorials/grpc/grpc-start
dotnet:
https://github.com/dotnet
grpc:
https://github.com/grpc
?.NET 上的 gRPC參考文檔
總結(jié)
以上是生活随笔為你收集整理的浅谈.NET 6 中 gRPC 的最新功能的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 路遥工具箱全面迁移至 .NET 6.0
- 下一篇: .NET Conf 2021 回顾