谈谈gRpc

142 阅读4分钟

参考up:孙哥
孙哥主页

gRPC简介

  1. gRPC 是由google开源的一个高性能的RPC框架。Stubby Google内部的RPC,演化而来的,2015正式开源。云原生时代是一个RPC标准。

  2. gRPC 核心的设计思路

  3. 网络通信 ---> gRPC自己封装网络通信的部分 提供多种语言的 网络通信的封装 (C Java[Netty] GO)

  4. 协议    ---> HTTP2 传输数据的时候 二进制数据内容。 支持双向流(双工)连接的多路复用。

  5. 序列化   ---> 基本文本 JSON  基于二进制 Java原生序列化方式 Thrift二进制的序列化 压缩二级制序列化。 protobuf (Protocol Buffers) google开源一种序列化方式  时间效率和空间效率是JSON的3---5倍。 IDL语言

  6. 代理的创建 --->让调用者像调用本地方法那样 去调用远端的服务方法。 stub

gprc与protobuf关系    1.grpc是RPC框架,而protobuf是grpc的序列化方式
  1. gRPC 与 ThriftRPC 区别 共性:支持异构语言的RPC。 区别:
  2. 网络通信 Thrift TCP   专属协议(Thrift定义的协议) GRPC   HTTP2(二进制协议,支持双工)
  3. 性能角度 ThriftRPC 性能 高于 gRPC
  4. gRPC 大厂背书(Google),云原生时代 与其他组件合作的顺利。所以gRPC应用更广泛。
  5. gRPC的好处
  6. 高效的进行进程间通信。
  7. 支持多种语言 原生支持 C  Go Java实现。C语言版本上扩展 C++ C# NodeJS Python Ruby PHP..
  8. 支持多平台运行 Linux Android IOS MacOS Windows。
  9. gPRC序列化方式采用protobuf,效率高。
  10. 使用Http2协议
  11. 大厂的背书

Http2.0协议

1. 回顾Http1.x协议
    Http1.0:   请求响应的模式  短连接协议 (无状态协议) 传输数据文本结构  单工 无法实现服务端推送
               实现推送(客户端轮询的方式),客户端每隔一段时间发一个请求(会增加服务端的压力)
    Http1.1: 请求响应的模式   有限的长连接 --->升级WebSocket 双工  实现服务器向客户端推送
总结: Http1.x协议  共性
  1. 传输数据文本的格式  可读性好  但是效率差
  2. 本质上无法实现双工通信
  3. 资源的请求: 需要发送多次请求  建立多个连接才可以完成 (静态资源+动态资源)

2. HTTP2.X协议
   1. Http2.0协议是一个二进制协议,效率高于Http1.x协议,可读性差
   2. 可用实现双工通信
   3. 一个请求 可以请求多个数据。【多路复用】
3. Http2.x协议的三个概念
   1. 数据流stream
   2. 消息  message
   3. 帧 frame
4. 其他的相关概念
   1. 数据流的优先级,可以通过不同的stream设置权重,来限制不同流的传输顺序
   2. 流控 client 发送的数据太快了。server处理不过来,通知client暂停数据的发送

Protocol Buffers [protobuf]

1. protobuf是一种与编程语言无关,与具体的平台无关,他定义的中间语言,可以方便再client与server
   中进行RPC的数据传输
2. rpotobuf  两种版本protobuf2,protobuf3 ,主要用protobuf3
3. protobuf主要安装protobuf的编译器,目的  可以把protobuf的IDL语言,转换成某一种具体开发语言

Protobuf编译器安装

github.com/protocolbuf… 安装3.19.6 github.com/protocolbuf… 解压缩 -添加环境变量 通过 protoc -version 查看是否安装成功

Protobuf IDEA的插件

Protobuf的语法详解

文件格式

.proto UserService.proto

版本设定

syntax="proto3";

注释

 单行//
 多行 /*  */
 

与java语言相关的语法

# 后续protobuf生成的java代码  一个源文件还是多个源文件  xx.java
option java_multiple_files=false;//设置一个源文件

# 指定protobuf生成的类 放置再哪个包中
option java_package=" ";

# 指定protobuf生成的外部类的名字  (管理内部类[内部类才是真正开发使用的])
option java_outhor_classname="UserService";

逻辑包(java可以不用)

package  xxx;
# protobuf 对于文件内容的管理

导入


UserService.proto

OrderService.proto
  improt "xxx/UserService.proto";
  使用UserServie.proto的内容

基本数据

枚举类型

enum SEASON{
  SPRING=0;
  SUMMER=1;
  }

枚举的值  必须从0开始

消息Message

message LoginRequest{

  string username=1;//1不是username 的值  是message中的一个编号
  string password=2;
  int32 age=3;
  }

编号  从1 开始 到 2^29-1  注意:19000-19999不能这个区间的编号,因为这是protobuf自己保留的
关键字:
-singular :默认    这个字段的值 只能是 0个或者1个  null/"123456"
-repeated  :
message Result{
  string content=1;
  repeated string status=2;//代表这个字段的返回值是多个 等价于java list getStatusList()->List
  }

protobuf 
可以定义多个消息

message LoginRequest{
  ...}
message LoginResponse{
  ...
  }
消息可以嵌套
message SearchResponse{
  message Result{
    string url =1;
    string title=2;
    }
  string xxx=1;
  int32 yyy=2;
  Result ppp=3;

  }

SearchResponse.Result

message AAA{
string xxx=1;
SearchResponse.Result yyy=2;
}

oneof[其中一个]  也就是test_oneof 只能是 name和age其中一个
message SimpleMessage{
  oneof test_oneof{
    string name=1;
    int32 age=2;
    }

  }

服务

service HelloService{
  rpc hello(HelloRequest) returns(HelloResponse){}
  }

# 里面可以定义多个服务方法
# 定义多个服务类/服务接口
# gRPC 服务 4个服务方式。。