grpc

grpc

Posted by ZW on November 21, 2020

http2.0

图一

参考 https://github.com/zqjflash/http2-protocol

protobuf

是什么

Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化,很适合做数据存储或 RPC 数据交换格式。它可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

语法

消息类型

message SearchRequest {
  required string query = 1;
  optional int32 page_number = 2;
  optional int32 result_per_page = 3;
  repeated string user_id=4;
}

1.required:表示该值是必须要设置的;

2.optional:消息格式中该字段可以有0个或1个值(不超过1个)。

3.repeated:字段可以重复任意多次(包括0次)。重复的值的顺序会被保留。表示该值可以重复,相当于java中的List。

每个字段都有唯一的一个数字标识符。这些标识符是用来在消息的二进制格式中识别各个字段的,一旦开始使用就不能够再改变

保留标识符或名称

message Foo {
  reserved 2, 15, 9 to 11;
  reserved "foo", "bar";
}

枚举

message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
  enum Corpus {
    UNIVERSAL = 0;
    WEB = 1;
    IMAGES = 2;
    LOCAL = 3;
    NEWS = 4;
    PRODUCTS = 5;
    VIDEO = 6;
  }
  Corpus corpus = 4;
}

Corpus枚举的第一个常量映射为0:每个枚举类型必须将其第一个类型映射为0,这是因为:

  1. 必须有有一个0值,我们可以用这个0值作为默认值。
  2. 这个零值必须为第一个元素,为了兼容proto2语义,枚举类的第一个值总是默认值。

导入其他proto文件

import "myproject/other_protos.proto";

更新一个消息类型

  1. 不要更改任何已有的字段的数值标识。
  2. 如果你增加新的字段,使用旧格式的字段仍然可以被你新产生的代码所解析。你应该记住这些元素的默认值这样你的新代码就可以以适当的方式和旧代码产生的数据交互。相似的,通过新代码产生的消息也可以被旧代码解析:只不过新的字段会被忽视掉。注意,未被识别的字段会在反序列化的过程中丢弃掉,所以如果消息再被传递给新的代码,新的字段依然是不可用的(这和proto2中的行为是不同的,在proto2中未定义的域依然会随着消息被序列化)

any

一个Any类型包括一个可以被序列化bytes类型的任意消息,以及一个URL作为一个全局标识符和解析消息类型。为了使用Any类型,你需要导入import google/protobuf/any.proto

import "google/protobuf/any.proto";

message ErrorStatus {
  string message = 1;
  repeated google.protobuf.Any details = 2;
}

Oneof

如果你的消息中有很多可选字段, 并且同时至多一个字段会被设置, 你可以加强这个行为,使用oneof特性节省内存.

message SampleMessage {
  oneof test_oneof {
    string name = 4;
    SubMessage sub_message = 9;
  }
}

定义service

service SearchService {
  rpc Search (SearchRequest) returns (SearchResponse);
}

option

在定义.proto文件时能够标注一系列的options。Options并不改变整个文件声明的含义,但却能够影响特定环境下处理方式。完整的可用选项可以在google/protobuf/descriptor.proto找到。

int32 old_field = 6 [deprecated=true];

map

如果你希望创建一个关联映射,protocol buffer提供了一种快捷的语法:

map<key_type, value_type> map_field = N;
map<string, Project> projects = 3;

grpc

gRPC 是一个高性能、通用的开源RPC框架,其由 Google 主要面向移动应用开发并基于HTTP/2 协议标准而设计,基于 ProtoBuf(Protocol Buffers) 序列化协议开发,且支持众多开发语言。本文作者深入研究了 gRPC 协议,对协议本身作出解构。

使用场景

  1. 内部微服务之间的通信。
  2. 高数据负载(gRPC 使用协议缓冲区,其速度最高可比 REST 调用快七倍)。
  3. 您只需要一个简单的服务定义,不需要编写完整的客户端库。

特性

  1. 使用Protocal Buffers这个强大的结构数据序列化工具
  2. grpc可以跨语言使用
  3. 安装简单,扩展方便(用该框架每秒可达到百万个RPC)
  4. 基于HTTP2协议

图形化调试工具

https://github.com/fullstorydev/grpcui

示例代码

https://github.com/grpc/grpc/tree/master/examples/python