protobuf 与 gRPC相关

https://zhuanlan.zhihu.com/p/149821222

 

RPC (Remote Procedure Call) 远程过程调用

将服务调用封装在一个本地方法中,让调用者像使用本地方法一样调用服务

调用方和服务方 约定,基于TCP长连接进行数据交互达成

 

由于方法不在本地执行,因此有三个特点:

1、 语义约定:事先约定调用的语义:调用语法

2、 网络传输

3、 编解码:需要约定网络传输的内容格式:压缩 解压缩

 

gRPC通过protobuf 和 HTTP2 实现这三大要素

 

用RabbitMQ 实现RPC服务形态

1、 调用: 方法调用->exchange->queue->方法执行

a)      创建direct类型的exchange 每个rpc方法对应一个queue,exchange 通过routing_key 将rpc分发到对应的queue中,特定的消费者可以执行rpc方法。语义可以通过queue约定,方法参数可以放入消息。

2、 结果回传:结果回传端->exchange->queue->结果等待段

a)      使用回调队列 Callback queue 实现回传,使用关联ID Correlation Id标识调用结果

3、 整体: 发送请求时,数据中带有routing_key 和关联ID,执行后将关联ID 掺入执行结果中,通过exchange发往回调队列。 调用参数和调用结果的打包可以用JSON或protobuf,只要协商一致即可。

 

protobuf

ProtocalBuffer 简称protobuf: 跨语言 跨平台 可拓展用于序列化数据的协议

// XXXX.proto

service Test {

    rpc HowRpcDefine (Request) returns (Response) ; // 定义一个RPC方法

}

message Request {

    //类型 | 字段名字|  标号

    int64    user_id  = 1;

    string   name     = 2;

}

message Response {

    repeated int64 ids = 1; // repeated 表示数组

    Value info = 2;         // 可嵌套对象

    map<int, Value> values = 3;    // 可输出map映射

}

message Value {

    bool is_man = 1;

    int age = 2;

}

protobuf特点:

1、 有明确的类型并支持多种类型

2、 字段有名字,且字段有数字编号,按顺序排列

3、 能表达数组 map映射等

4、 可以通过嵌套 表达复杂的队形

5、 方法 参数 都定义到一个proto文件中 双方都同时持有这个文件 进行编解码

Protobuf提供protoc工具,由c++编写,可以通过proto文件,生成特定语言的中间代码

//       依赖目录      生成golang中间代码   对应proto文件地址
protoc -I=$SRC_DIR --go_out=$DST_DIR  $SRC_DIR/XXX.proto
protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/XXX.proto // 生成java中间代码

 

JSON,protobuf对比

1、 JSON传递字段名,protobuf只需要传递字段标号,更节约空间

2、 JSON数字用字符串表达,例如123一个字节就能表示的 用字符串则需要3个字节,protobuf直接用二进制表达内容

3、 JSON 用逗号 括号来分割字段和建立层次结构,protobuf未使用分隔符,而是将最高位置1来标记数据是否解析完毕。

 

解析过程:

T-V : tag 字段标识号 value 消息字段经过编码后的值

T-L-V:tag 字段标识号 length value字节的长度 value 消息字段经过编码后的值

数组:不断的重复T-V

嵌套队形:T-V ,在V中继续存T –V 逐层解析

 

优点:

1、   不打包无用数据 排列紧凑 体积小 利于传输

2、   解析策略简单 序列化 反序列化快

3、   能较好的兼容字段(未找到的字段标号会跳过)

 

缺点:

1、   人无法直接看出各个字段的值

2、   需要proto文件才能解析

 

 

HTTP2

 

HTTP1.1 缺点:

1、 冗余文本过多,导致传输体积很大。无状态协议,每个请求都会带上冗余重复的Header,消耗空间

2、 并发能力差,网络资源利用率低。请求内容打包在header/body中,同一个TCP连接中,无法区别response属于哪个请求,无法并发的发送多个请求,只能等上一个response回来了才能发送下一个请求。 Pipline特性允许请求方一次发送多个request,但需要顺序返回response,但存在队首阻塞问题,若第一个request迟迟不返回,就将在此阻塞。

 

HTTP2 优点:

1、 头部压缩:将高频使用的Header编成静态表,可直接使用静态表中的编号代替某些字段。且可以通过HPACK动态的在表中增加HEADER,连接销毁时动态表注销。通过静态表和动态表使用编号代替某些内容,大大的节约了空间。

2、 多路复用:提出了流的概念,每次请求对应一个流,且有唯一ID,为了方便的进行数据分割传输,又将数据分为多个帧,每帧属于某个唯一的流ID。这样TCP可以同时并发多个请求,不同请求的帧数据可以穿插在一起,复用了单个TCP连接,不需要同时建立多个TCP连接,提高TCP连接的利用效率。

 

 

服务发现:

1、   A要得到B的可调用地址

2、   B的部署方式可能多种多样

3、   名称发现协议 scheme://authority/endpoint_name

a)      Schme 服务发现系统的名称 如DNS 或自研其他

b)      Authority 特定方案的引导信息

c)      Endpoint_name 服务的具体名字

4、   通过名称发现协议可以 得到一批 IP:port

5、   提供了名称系统注册能力

 

负载均衡:

1、 选哪个IP:port

2、 方*询 随机 耗时最短 加权随机等

3、 提供了负载均衡策略接口

上一篇:【RPC❄️006】python3体验protobuf魅力


下一篇:使用JsonFormat映射protobuf和javabean