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

 

posted @ 2020-03-22 15:39  圆圆酥  阅读(5150)  评论(0编辑  收藏  举报