ASP.NET Core 3.0 使用gRPC
一.簡介
gRPC 是一個由Google開源的,跨語言的,高效能的遠端過程呼叫(RPC)框架。 gRPC使客戶端和服務端應用程式可以透明地進行通訊,並簡化了連線系統的構建。它使用HTTP/2作為通訊協議,使用 Protocol Buffers 作為序列化協議。
它的主要優點:
- 現代高效能輕量級 RPC 框架。
約定優先的 API 開發,預設使用 Protocol Buffers 作為描述語言,允許與語言無關的實現。
- 可用於多種語言的工具,以生成強型別的伺服器和客戶端。
- 支援客戶端,伺服器雙向流呼叫。
- 通過Protocol Buffers二進位制序列化減少網路使用。
使用 HTTP/2 進行傳輸
這些優點使gRPC非常適合:
- 高效能輕量級微服務。
- 需要多種程式語言同時使用的專案。
- 需要處理流式請求或響應的點對點實時服務。
摘自微軟官方文件
支援的語言如下:
二.gRPC on .NET Core
gRPC 現在可以非常簡單的在 .NET Core 和 ASP.NET Core 中使用,在 .NET Core 上的實現的開源地址:https://github.com/grpc/grpc-dotnet ,它目前由微軟官方 ASP.NET 專案的人員進行維護,良好的接入 .NET Core 生態。
.NET Core 的 gRPC 功能如下:
- Grpc.AspNetCore 一個用於在ASP.NET Core承載gRPC服務的框架,將 gRPC和ASP.NET Core 功能整合在一起,如:日誌、依賴注入、身份認證和授權。
- Grpc.Net.Client 基於HttpClient (HttpClient現已支援HTTP/2)的 gRPC客戶端
- Grpc.Net.ClientFactory 與gRPC客戶端整合的
HttpClientFactory
,允許對gRPC客戶端進行集中配置,並使用DI注入到應用程式中
三.使用 ASP.NET Core 建立 gRPC 服務
- 通過 Visual Studio 2019 (16.3.0)提供的模板,可以快速建立 gRPC 服務。
來扒拉一下預設原始碼包含了什麼東東。
① 配置檔案 appsettings.json
,多了Kestrel 啟用 HTTP/2 的配置,因為 gRPC 是基於 HTTP/2 來通訊的
② PB協議檔案 greet.proto
用於自動生成服務、客戶端和訊息(表示傳遞的資料)的C# Class
③ 服務類 GreeterService
,服務類整合的 Greeter.GreeterBase
來自於根據proto檔案自動生成的,生成的類在 obj\Debug\netcoreapp3.0
目錄下
自動生成的類:
④ Startup.cs
類,將 gRPC服務新增到了終結點路由中
⑤ csproj 專案檔案,包含了 proto 檔案引用
2.執行
第一次執行會提示是否信任證書,點選“是”
這是因為HTTP/2需要HTTPS,儘管HTTP/2協議沒有明確規定需要HTTPS,但是為了安全在瀏覽器實現上都要求了HTTPS,所以現在的HTTP/2和HTTPS基本都是一對。
四. 建立 gRPC 客戶端
1.新增一個.NET Core 控制檯應用程式
2.通過nuget新增包:Grpc.Net.Client、Google.Protobuf、Grpc.Tools
3.將服務的 proto 檔案複製到客戶端
4.編輯客戶端專案檔案,新增關於proto檔案的描述
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
</ItemGroup>
注意 GrpcServices="Client"
這裡是Client和服務是不一樣的
5.生成客戶端專案可以通過proto檔案生成類
6.新增客戶端呼叫程式碼
static async Task Main(string[] args)
{
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
new HelloRequest { Name = "曉晨" });
Console.WriteLine("Greeter 服務返回資料: " + reply.Message);
Console.ReadKey();
}
7.先啟動服務,然後執行客戶端
這裡可以看到,客戶端成功呼叫了服務,收到了返回的訊息。
五.自己動手寫一個服務
前面我們使用的 Greeter 服務是由模板自動給我們建立的,現在我們來自己動手寫一個服務。
編寫一個“擼貓服務”
1.定義 proto 檔案 LuCat.proto
,並在csproj專案檔案中新增描述
syntax = "proto3";
option csharp_namespace = "AspNetCoregRpcService";
import "google/protobuf/empty.proto";
package LuCat; //定義包名
//定義服務
service LuCat{
//定義吸貓方法
rpc SuckingCat(google.protobuf.Empty) returns(SuckingCatResult);
}
message SuckingCatResult{
string message=1;
}
2.實現服務 LuCatService.cs
public class LuCatService:LuCat.LuCatBase
{
private static readonly List<string> Cats=new List<string>(){"英短銀漸層","英短金漸層","美短","藍貓","狸花貓","橘貓"};
private static readonly Random Rand=new Random(DateTime.Now.Millisecond);
public override Task<SuckingCatResult> SuckingCat(Empty request, ServerCallContext context)
{
return Task.FromResult(new SuckingCatResult()
{
Message = $"您吸了一隻{Cats[Rand.Next(0, Cats.Count)]}"
});
}
}
3.在 Startup
終結點路由中註冊
endpoints.MapGrpcService<LuCatService>();
4.新增客戶端呼叫
var catClient = new LuCat.LuCatClient(channel);
var catReply = await catClient.SuckingCatAsync(new Empty());
Console.WriteLine("呼叫擼貓服務:"+ catReply.Message);
5.執行測試
六.實際使用中的技巧
技巧1
上面章節的操作步驟中,我們需要在服務和客戶端之間複製proto,這是一個可以省略掉的步驟。
1.複製 Protos 資料夾到解決方案根目錄(sln檔案所在目錄)
2.刪除客戶端和服務專案中的 Protos 資料夾
3.在客戶端專案檔案csproj中新增關於proto檔案的描述
<ItemGroup>
<Protobuf Include="..\..\Protos\greet.proto" GrpcServices="Client" Link="Protos\greet.proto" />
</ItemGroup>
4.在服務專案檔案csproj中新增關於proto檔案的描述
<ItemGroup>
<Protobuf Include="..\..\Protos\greet.proto" GrpcServices="Server" Link="Protos\greet.proto" />
</ItemGroup>
在實際專案中,請自己計算相對路徑
5.這樣兩個專案都是使用的一個proto檔案,只用維護這一個檔案即可
技巧2
我們在實際專案中使用,肯定有多個 proto 檔案,難道我們每新增一個 proto 檔案都要去更新 csproj檔案?
我們可以使用MSBuild變數來幫我們完成,我們將 csproj 專案檔案中引入proto檔案資訊進行修改。
服務端:
<ItemGroup>
<Protobuf Include="..\..\Protos\*.proto" GrpcServices="Server" Link="Protos\%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
客戶端:
<ItemGroup>
<Protobuf Include="..\..\Protos\*.proto" GrpcServices="Client" Link="Protos\%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
示例:
七.總結
gRPC 現目前是一款非常成熟的高效能RPC框架,當前的生態是非常好的,很多公司的產品或者開源專案都有在使用gRPC,有了它,相信可以讓我們更容易的構建.NET Core 微服務,可以讓 .NET Core 更好的接入 gRPC 生態。不得不說這是 .NET Core 3.0 帶來的最令人振奮的特性之一。
參考資料:
- proto3 說明文件
- 在ASP.NET Core中建立gRPC客戶端和服務
- Demo 地址
如果大家無法訪問proto3說明文件,這裡提供一個離線網頁版(請另存為下載後用Chrome開啟)