官方的定義:ios
gRPC is a modern open source high performance RPC framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication. It is also applicable in last mile of distributed computing to connect devices, mobile applications and browsers to backend services.程序員
gRPC是一種現代化開源的高性能RPC框架,可以運行於任意環境之中。它能夠高效地在服務和數據中心內部與其間創建鏈接,而且可支持負載均衡,追蹤,健康檢測與認證功能。同時它也可用於分佈式計算的「最後一千米」,鏈接設備,移動應用和瀏覽器到後端服務。web
維基的定義:後端
gRPC (gRPC Remote Procedure Calls) is an open source remote procedure call (RPC) system initially developed at Google. It uses HTTP/2 for transport, Protocol Buffers as the interface description language, and provides features such as authentication, bidirectional streaming and flow control, blocking or nonblocking bindings, and cancellation and timeouts. It generates cross-platform client and server bindings for many languages. Most common usage scenarios include connecting services in microservices style architecture and connect mobile devices, browser clients to backend services.api
gRPC(gRPC遠程過程調用)是一種開源的遠程過程調用系統,最初由谷歌進行開發。它使用HTTP/2做爲傳輸協議。Protocol Buffer被用於接口描述語言,提供了諸如認證,雙向流控制,阻塞或非阻塞綁定,取消與超時功能。它爲多種語言生成跨平臺的客戶端與服務端綁定。最通用的使用場景包括在微服務樣式架構中鏈接服務,以及鏈接移動設備,瀏覽器客戶端到後端服務。瀏覽器
從上面的解釋裏不難看出,要對gRPC有更直觀的理解,首先須要明白RPC的定義。網絡
繼續看下維基上的內容:數據結構
In distributed computing, a remote procedure call (RPC) is when a computer program causes a procedure (subroutine) to execute in a different address space (commonly on another computer on a shared network), which is coded as if it were a normal (local) procedure call, without the programmer explicitly coding the details for the remote interaction. That is, the programmer writes essentially the same code whether the subroutine is local to the executing program, or remote. This is a form of client–server interaction (caller is client, executor is server), typically implemented via a request–response message-passing system. In the object-oriented programming paradigm, RPC calls are represented by remote method invocation (RMI). The RPC model implies a level of location transparency, namely that calling procedures is largely the same whether it is local or remote, but usually they are not identical, so local calls can be distinguished from remote calls. Remote calls are usually orders of magnitude slower and less reliable than local calls, so distinguishing them is important.架構
在分佈式計算裏,當計算機程序要運行一段代碼,遠程過程調用(RPC)會在不一樣的內存地址(通常是在網絡裏的不一樣計算機)上執行它。其無需程序員顯示地對它的遠程交互進行具體編碼,編寫代碼的方式就如同一段普通的本地過程調用通常。便是,程序員所需寫的代碼是相同的,不管其調用的過程是在本地仍是遠程。這是一種客戶端-服務端交互的形式(調用方是客戶端,執行方是服務端),典型的實現方式是經過一種請求-響應的傳遞消息系統。在面向對象程序範式裏,RPC調用被表示爲遠程方式調用(RMI)。RPC模型意味着必定程度的本地透明性,本地或是遠程的調用過程大體而言是等同的,但又不是徹底同樣。遠程調用一般比本地調用慢上幾個數量級,同時也更加不可靠。app
若是對RPC的概念仍是理解不了的話,卻曾使用過或者瞭解過諸如Remoting,Web Service或者WCF等技術的話,那麼其實在這方面已經入門了。
Protocol buffers是谷歌開發的一套無關開發語言,無關平臺的用於序列化結構數據的可擴展機制。它的用途與XML,JSON相同,但比它們更小,更快,更簡潔。
做爲gRPC中默認的接口定義語言,其既能夠用於定義服務接口,也能夠定義所必要的數據結構。
service HelloService { rpc SayHello (HelloRequest) returns (HelloResponse); } message HelloRequest { string greeting = 1; } message HelloResponse { string reply = 1; }
Protocol buffers的代碼須要保存在擴展名爲.proto
的文件之中。
gRPC支持四種服務類型:
一元式RPC,如同普通的方法調用通常,客戶端的單一請求,至服務端後,返回惟一的響應。
rpc SayHello(HelloRequest) returns (HelloResponse){ }
服務端流式RPC,客戶端發送一請求至服務端後,服務端返回一串消息數據流,客戶端持續讀取直到沒有更多的消息。gRPC會確保消息的傳輸順序。
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){ }
客戶端流式RPC,客戶端對一數據流寫入一串信息後發送到服務端,並等待服務端返回響應。gRPC會確保消息的傳輸順序。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) { }
雙向流式RPC,客戶端與服務端使用兩個數據流,其間互無影響,能夠同時進行數據傳遞。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){ }
光有proto文件,並不能直接使用,還需gRPC中所提供的API將這些文件編譯成不一樣程序語言的服務端與客戶端代碼。
在服務端,實現服務所定義的方法,並運行gRPC服務程序以處理客戶端調用。gRPC架構負責解碼傳入的請求,執行服務的方法,最後對服務的響應進行編碼。
在客戶端,會有一個名爲存根(stub)的本地對象,實現與服務端相同的方法。這樣只需調用這個本地對象的方法,傳入合適的protocol buffers消息類型的參數,gRPC負責將請求發送至服務端,再返回相應的結果。
若是使用過諸如WCF這樣的PRC技術,對這一過程應該是十分熟悉了。
感到陌生的大概是gRPC中將proto文件編譯成代碼的插件工具,例如Grpc.Tools
。
因此仍是舉個具體的例子以便理解。
首先創建兩個Console工程。
dotnet new console -o gRPCServer dotnet new console -o gRPCClient
接着,在此兩個工程同級目錄下新建一個名爲protos的文件夾。
如此,目錄下的文件夾應該有以下幾個:
protos文件夾下新加一個greet.proto文件。
syntax = "proto3"; option csharp_namespace = "GrpcGreeter"; package Greet; // The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply); } // The request message containing the user's name. message HelloRequest { string name = 1; } // The response message containing the greetings. message HelloReply { string message = 1; }
而後,進入gRPCServer文件夾,添加相關的類庫包。
dotnet add package Grpc dotnet add package Grpc.Tools dotnet add package Google.Protobuf
並在csproj文件中加入下列配置:
<ItemGroup> <Protobuf Include="../protos/*.proto" OutputDir="protos" CompileOutputs="false" GrpcServices="Service" /> </ItemGroup>
運行dotnet build
,能夠看到在gRPCServer工程下新生成一個protos文件夾,以及Greet.cs與GreetGrpc.cs文件。
在Program類中加入Greeter的實現類和相關接口方法,並建立服務端啓動程序。
class Program { const int Port = 51234; static void Main(string[] args) { var server = new Server { Services = { Greeter.BindService(new GreeterImpl()) }, Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) } }; server.Start(); Console.WriteLine("Greeter server listening on port " + Port); Console.WriteLine("Press any key to stop the server..."); Console.ReadKey(); server.ShutdownAsync().Wait(); } } class GreeterImpl : Greeter.GreeterBase { // Server side handler of the SayHello RPC public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context) { return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); } }
經過dotnet run
命令啓動此服務端。
以後再進入gRPCClient文件夾,加入一樣的類庫包。
在csproj文件中加入相似的配置,注意GrpcServices屬性改成了Client:
<ItemGroup> <Protobuf Include="../protos/*.proto" OutputDir="protos" CompileOutputs="false" GrpcServices="Client" /> </ItemGroup>
運行dotnet build
,一樣生成protos文件夾及兩個proto文件。
Program類中加入客戶端調用代碼。
static void Main(string[] args) { var channel = new Channel("127.0.0.1:51234", ChannelCredentials.Insecure); var client = new Greeter.GreeterClient(channel); var reply = client.SayHello(new HelloRequest { Name = "Ken" }); Console.WriteLine(reply.Message); channel.ShutdownAsync().Wait(); Console.ReadKey(); }
運行客戶端後,應該就能夠看到調用服務端方法後返回的結果。
在最新的.NET Core 3.0中,加入了對gRPC更多的支持。當建立一個Web項目時,選擇ASP.NET Core 3.0,能夠發現新增了gRPC Service項目模板。
從創建的項目代碼中能夠看出其再也不是普通的Web應用,而是徹底變成了gRPC的服務端。
public void ConfigureServices(IServiceCollection services) { services.AddGrpc(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseEndpoints(endpoints => { // Communication with gRPC endpoints must be made through a gRPC client. // To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909 endpoints.MapGrpcService<GreeterService>(); }); }