gRPC簡介並使用


一、簡介

        gRPC來自Goole,它是一個開源的框架;它同時也是Cloud Native Computation的基金會(CNCF)的一部分,就像Docker和Kubernetes一樣。

       gRPC允許你為RPC(Remote Procedure Call)定義請求和響應,然后gRPC會幫你處理一切剩余的問題。

        它速度快,執行效率高,基於HTTP/2構建,低延遲,支持流,與開發語言無關,並且可以很簡單的插入身份認證、負載均衡、日志和監控等功能。

        gRPC它是對RPC一種非常簡潔的實現並且解決了很多RPC的問題。

       

 

        如何學習gRPC,首先學習Protocol Buffers,簡單的說,它可以用來定義消息和服務。然后,你只需要實現服務即可,剩余的gRPC代碼將會自動為你生成。.proto這個文件可以適用於十幾種開發語言,並且允許你使用同一個框架來支持每秒百萬級以上的RPC調用。

        開發模式:gRPC使用合約優先的API開發模式,它默認使用Protocol buffers(protobuf)作為接口設計語言,這個.proto文件包括兩部分:

                          1)gRPC服務的定義;

                          2)服務端和客戶端之間傳遞的消息;

       開發環境,首先需要安裝Clang:https://releases.llvm.org/download.html

        

 

 

      VSCode 中需要安裝vscode-proto3和Clang-Format

      

 

 

      

 

 

二、Protocol Buffers

  1、標量類型

  

 

 

  消息定義:

syntax="proto3";

message Person{
  int32 is=1;
  string name =2;
  float height=3;
  float weight=4;
  bytes avatar=5;
  string email=6;
  bool email_verified=7;
}

 

2、字段的數值(Tag)

 在Protocol Buffers里面,字段的名稱其實沒那么重要,但是寫C#代碼的時候,字段名還是很重要的。對於protobuf來說,這個tag是更重要的,可以使用的最小tag數值是1,最大值是229-1,或者536,870,911。但是你不可以使用19000到19999之間的數,這部分數是保留的。

 還有一點需要注意:

        從1到15的tag數只占用1個字節的空間,所以它們應該被用在頻繁使用的字段上。而從16到2047,則占用兩個字節,它們可以用字不頻繁使用的字段上。

3、字段規則

protobuf 的字段必須滿足以下兩個規則之一:

1)單數字段(Singular):大概意思就是指這個字段只能出現0或1次,這也是proto3的默認字段規則;

2)重復字段(Repeated):如果你想做一個list或數組的話,你可以使用重復字段這個概念,這個list可以有任何數量(包括0)的元素,它里面的值的順序將會得到保留。

repeated string phone_numbers=8;//packed

 

4、保留字段

   

reserved 9,10,20 to 100,200 to max;
reserved "foo","bar";

 

5、字段的默認值

 當消息被解析的時候,如果編碼的消息里不包含特定的一個sinular元素,那么在被解析對象里響應的字段就會被設為默認值。

 常用類型的默認值如下:

    string:空字符串

    bytes:空的byte數組

   bool:false

   數值型:0

   枚舉:枚舉里定義的第一個枚舉值,值必須是0。

   repeated:通常是相應開發語言里的空list

   還有一個消息類型的字段,它的默認值與開發語言有關。

6、枚舉

  枚舉Enum的tag必須從0開始,它可以起別名,起別名的作用就是允許兩個枚舉值擁有同一個數值。想要起別名,首先需要設置allow_alias這個option為true.

  常量值不能超過32位整形的數值,枚舉可以定義在message里面,也可以再外邊單獨定義以便復用。

Gender gender=11;
enum Gender{
option allow_alias=true;
NOT_SPECIFIED=0;
FEMALE=1;
MALE=2;
WOMAN=1;
MAN=2;
}

 

7、自定義消息類型

syntax="proto3";

import "date.proto";
message Person{
  int32 is=1;
  string name =2;
  float height=3;
  float weight=4;
  bytes avatar=5;
  string email=6;
  bool email_verified=7;
  repeated string phone_numbers=8;//packed

  Gender gender=11;
  Date birthday=12;

  reserved 9,10,20 to 100,200 to max;
  reserved "foo","bar";
  
  repeated Address addresses=13;
  message Address{
    string province=1;
    string city=2;
    string street=3;
  }
}

enum Gender{
  option allow_alias=true;
  NOT_SPECIFIED=0;
  FEMALE=1;
  MALE=2;
  WOMAN=1;
  MAN=2;
}

 

8、打包

你可以向proto文件添加可選的打包(package)說明符,以避免消息類型間的名稱沖突。

package my.project;
option csharp_namespace="Test_Namespace";

 

9、設置Protocol Buffers編譯器  

    protoc編譯器主要是用來生成代碼的,下載地址:https://github.com/protocolbuffers/protobuf/releases/

    

 

 

 下載后解壓,添加環境變量:

  

 

 

  輸入命令行protoc看一下是否正常:

 

 

 -IPATH 用來指定哪個文件夾下有我們需要的引用;

 

 

 指定對應語言生成的路徑

打開VSCode終端,執行:

 

 

 生成C#文件:

 

 

 生成的文件不要隨意改動,需要更改就改.proto文件。

三、更新消息類型

 隨着需求的變更,消息的字段可能會發生一些變化,可能很多程序都在使用這個消息,那么,我們在對源數據進行演進的時候,一定不要引起破壞性的變化,否則其他程序可能就無法正常工作了。

 兩種變更情景:

     向前兼容變更:使用新的.proto文件來寫數據--從舊的.proto文件讀取數據

     向后兼容變更:使用舊的.proto文件來寫數據--從新的.proto文件讀取數據

    

 

 

 四、gRPC的原理

   

 

 

   設計步驟:

  

 

 生命周期:

  

 

 身份認證:

  

 五、在.Net Core中應用gRPC

  新建一個gRPC項目:

   

 

 

 結構如下:

 

 

 先寫Proto文件,定義消息:

 

 

 然后定義Servers:

public class GreeterService : Greeter.GreeterBase
    {
        public override Task<HelloReply> SayHello(
             HelloRequest request, ServerCallContext context)
        {
            return Task.FromResult(new HelloReply
            {
                Message = "Hello " + request.Name
            });
        }
    }

 

配置 gRPC

在 Startup.cs 中 :

  • gRPC 通過 AddGrpc 方法啟用。
  • 每個 gRPC 服務均通過 MapGrpcService 方法添加到路由管道
public void ConfigureServices(IServiceCollection services)
        {
            services.AddGrpc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGrpcService<GreeterService>();
            });
        }

 

現在在.Net客戶端調用gRPC服務:

新建一個控制台項目,配置文件修改:

 

 gRPC 客戶端是通過通道創建的。 首先使用 GrpcChannel.ForAddress 創建一個通道,然后使用該通道創建 gRPC 客戶端:

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 = "GreeterClient" });
            Console.WriteLine("Greeting: " + reply.Message);
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }

 

具體參考:https://docs.microsoft.com/zh-cn/aspnet/core/grpc/client?view=aspnetcore-3.1

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM