淺談.NET 6 中 gRPC 的最新功能
微軟中國MSDN 點選上方 藍字 關注我們
gRPC 是一個現代的、跨平臺的、高效能的 RPC 框架。gRPC 是構建在 ASP.NET Core 之上,也是我們推薦的使用 .NET 構建 RPC 服務的方法。
.NET 6 進一步提高了 gRPC 已經非常出色的效能,並添加了一系列新功能,使 gRPC 在現代雲原生應用程式中比以往任何時候都更好。在這篇文章中,我將描述這些新功能以及我們如何通過第一個支援端到端 HTTP/3 的 gRPC 實現引領行業。

gPRC 客戶端負載均衡
客戶端負載平衡是一項允許 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" });
更多資訊,請參閱 gPRC 客戶端負載平衡 。
-
gPRC
https://docs.microsoft.com/aspnet/core/grpc/
-
gPRC 客戶端負載平衡:
https://docs.microsoft.com/aspnet/core/grpc/loadbalancing

帶有重試的瞬間故障處理
gRPC 呼叫可能會被瞬時故障中斷。瞬態故障包括:
-
網路連線暫時中斷。
-
服務暫時不可用。
-
由於伺服器負載超時。
當 gRPC 呼叫被中斷時,客戶端會丟擲一個包含錯誤詳細資訊的 RpcException。客戶端應用程式必須捕獲異常並選擇如何處理錯誤。
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.
}
在整個應用程式中複製重試邏輯是冗長且容易出錯的。幸運的是,.NET gRPC 客戶端現在內建了對自動重試的支援。重試在通道上集中配置,並且有許多選項可用於使用 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 }}
});
有關更多資訊,請參閱 使用 gRPC 重試進行瞬態故障處理 。
-
使用 gPRC 重試進行瞬態故障處理:
https://docs.microsoft.com/aspnet/core/grpc/retries

Protobuf 效能
關於.NET 的 gRPC 使用 Google.Protobuf 包作為訊息的預設序列化程式。Protobuf 是一種高效的二進位制序列化格式。Google.Protobuf 旨在提高效能,使用程式碼生成而不是反射來序列化 .NET 物件。在 .NET 5 中,我們與 Protobuf 團隊合作,為序列化程式添加了對現代記憶體 API(例如 Span<T>、ReadOnlySequence<T>和IBufferWriter<T>)的支援。.NET 6 中的改進優化了一個已經很快的序列化程式。
protocolbuffers/protobuf#8147添加了向量化字串序列化。SIMD 指令允許並行處理多個字元,從而在序列化某些字串值時顯著提高效能。
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 添加了一個用於建立 ByteString 例項的新 API。如果你知道底層資料不會改變,那麼使用 UnsafeByteOperations.UnsafeWrap 來建立一個 ByteString 而不復制底層資料。如果應用程式處理大位元組有效負載並且您想降低垃圾收集頻率,這將非常有用。
-
protocolbuffers/protobuf#7645:
https://github.com/protocolbuffers/protobuf/pull/7645

gPRC 下載速度
gRPC 使用者報告有時下載速度變慢。我們的調查發現,當客戶端和伺服器之間存在延遲時,HTTP/2 流量控制會限制下載。伺服器在客戶端可以耗盡之前填充接收緩衝區視窗,導致伺服器暫停傳送資料。gRPC 訊息以開始/停止突發方式下載。
這已在 dotnet/runtime#54755 中修復。HttpClient 現在動態縮放接收緩衝區視窗。建立HTTP/2 連線後,客戶端將向伺服器傳送 ping 以測量延遲。如果存在高延遲,客戶端會自動增加接收緩衝區視窗,從而實現快速、連續的下載。
privateGrpcChannel _channel =GrpcChannel.ForAddress(...);
privateDownloadClient _client =newDownloadClient(_channel);
[Benchmark]
publicTaskGrpcLargeDownload()=>
_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 |
-
dotnet/runtime#54755
https://github.com/dotnet/runtime/pull/54755

HTTP/3 支援
NET 上的 gRPC 現在支援 HTTP/3。gRPC 建立在 .NET 6 中新增到 ASP.NET Core 和 HttpClient 的 HTTP/3 支援之上。有關更多資訊,請參閱 .NET 6 中的 HTTP/3 支援。
.NET 是第一個支援端到端 HTTP/3 的 gRPC 實現,我們已經為其他平臺 提交了 gRFC ,以便將來支援 HTTP/3。帶有 HTTP/3 的 gRPC 是 開發人員社群高度要求的功能 ,很高興看到 .NET 在該領域處於領先地位。
-
.NET 6 中的 HTTP/3 :
https://devblogs.microsoft.com/dotnet/http-3-support-in-dotnet-6/
-
gRFC:
https://github.com/grpc/proposal/pull/256
-
開發人員社群高度要求的功能:
https://github.com/grpc/grpc/issues/19126
總結


效能是 .NET 和 gRPC 的一個特性,而 .NET 6 比以往任何時候都快。客戶端負載平衡和 HTTP/3 等以效能為導向的新功能意味著更低的延遲、更高的吞吐量和更少的伺服器。這是一個節省資金、減少能耗和 構建更環保的雲原生應用程式 的機會。
要試用新功能並開始在 .NET 中使用 gRPC ,最好的起點是在 ASP.NET Core 教程中建立 gRPC 客戶端和伺服器。
我們期待聽到有關使用 gRPC 和 .NET 構建的應用程式以及您 在 dotnet 和 grpc 儲存庫中的貢獻!
-
構建更環保的雲原生應用程式 :
https://docs.microsoft.com/aspnet/core/tutorials/grpc/grpc-start
-
dotnet:
https://github.com/dotnet
-
grpc:
https://github.com/grpc
.NET 上的 gRPC參考文件
- 由世紀互聯運營的 Power Apps Portals 正式在華商用
- 在嗎?看看MAUI候選版本3!
- 官宣 .NET 7 預覽版3
- 疫情影響企業發展能力?也許它能幫您擺脫困境
- 做⼀個可以聊天的 VS Code 外掛
- .NET MAUI候選版本,能帶給你什麼小驚喜?
- 加速Spring現代化,我們做了什麼?
- 啤酒也上雲?來看看嘉士伯的獨家配方!
- 更新丨.NET 7 預覽版2 中的 ASP.NET Core
- Demo丨GitHub Codespaces,雲上開發完整專案
- Java on Visual Studio Code 3月更新
- .NET Core 分析程式集更優方法,超越ReflectionOnlyLoad
- 深入瞭解 Azure 機器學習的工作原理
- ASP.NET Core 6 的效能改進
- 叮,您有一份ML.NET 速查手冊請查收!
- 【位元熊故事匯】2月MVP英雄故事|有愛的開源
- 使用 Source Generators 快速編寫 MVVM 程式碼
- C# 10的新特性
- 使用 C# 獲取 Kubernetes 叢集資源資訊
- 理想同學:今年的春節是“微軟味"的