gRCP - 面向未来的第二代 RPC 技术,解析 HTTP2.0 和 Protobuf

目录

一、gRCP - 面向未来的第二代 RPC 技术

1.1、gRPC 简介

1.1.1、gRPC 是个啥?

1.1.2、gRPC 核心设计思路

1.1.3、gRPC 和 ThriftRPC 区别

1.1.4、为什么使用 gRPC?(好处)

1.2、HTTP2.0 协议

1.2.1、回顾 HTTP1.0 和 HTTP1.1

1.2.2、HTTP2.0 协议

1.3、Protocol Buffers(Protobuf)

1.3.1、protobuf 是什么

1.3.2、安装 Protobuf 编译器

1.3.3、protobuf 语法


一、gRCP - 面向未来的第二代 RPC 技术


1.1、gRPC 简介

1.1.1、gRPC 是个啥?

gRPC 是 Google 开源的一个高性能的 RPC 框架,高效实现进程间通信。Studdy Google 内部的 RPC 演化而来,2015 正式开源. 云原生时代是一个 RPC 标准.

1.1.2、gRPC 核心设计思路

对于远程调用的的设计思路,一般都是以下四个方面:

  1. 网络通信:gRPC 自己封装网络通信的部分,并提供多种语言的封装(C、Java[Nerry]、GO).
  2. 协议:gRPC 使用 HTTP2 传输数据(二进制数据内容),支持双工(双向流)连接的多路复用.
  3. 序列化:基于 Protobuf 的序列化方式,时间效率和空间效率都是 JSON 的 3~5 倍.
  4. 代理的创建:让调用者像调用本地方法一样,去调用远端的服务方法.

1.1.3、gRPC 和 ThriftRPC 区别

共同点:支持异构语言的 RPC.

不同点:

  1. 网络通信:ThriftRPC 使用 TCP 专属协议.  gRPC 使用 HTTP2 协议.
  2. 性能方面:ThriftRPC 高于 gRPC.
  3. 应用广度:gRPC 大厂背书(Google),云原生时代和其他组件合作很顺利,因此应用更广泛.

1.1.4、为什么使用 gRPC?(好处)

  1. 高效:基于 HTTP2 协议,传输二进制数据内容,又基于 Protobuf 实现序列化,高效的进行进程间通信.
  2. 支持多种语言:原生支持 C、GO、Java 实现。C语言版本上可扩展 C++、C#、NodeJS、Python、Ruby、PHP.
  3. 跨平台:支持多平台运行 linux、Android、IOS、MacOS、Windows.
  4. 大厂背书:Google 力推.

1.2、HTTP2.0 协议

1.2.1、回顾 HTTP1.0 和 HTTP1.1

HTTP1.0 协议:

  • 请求响应模式:一个请求对应一个响应.
  • 短链接协议:无状态协议,客户端不认识服务器,反之也一样,可引入 Session - Cookie 机制解决.
  • 传输数据:文本结构.
  • 单工:无法实现服务端推送机制,要实现必须让客户端 "轮询".

HTTP1.1 协议:

  • 请求响应模式:一个请求对应一个响应.
  • 有限长连接:可升级为 WebSocket 协议,实现服务器向客户端的消息推送机制.
  • 传输数据:文本结构.
  • 双工:服务器可对客户端进行消息推送.

可以看出,HTTP1.x 协议的共性如下:

  • 传输数据都是文本格式,可读性好,但是效率差.
  • 本质上 HTTP1.x 协议无法实现双工通信.
  • 关于资源请求,需要发送多次请求,建立多个连接才可以完成.  例如一般发送一个请求第一次请求到的是一个 HTML 格式的数据,然后还需要继续发两次请求,以异步的方式请求 JS 和 CSS 文件(网络通信也是需要开销的,三次握手、四次挥手......).

1.2.2、HTTP2.0 协议

  • 二进制通信:HTTP2.0 协议是一个二进制协议,效率高于 HTTP1.x,但是可读性较差.
  • 实现双工通信:服务器可对客户端进行消息推送.
  • 实现了多路复用机制:一个连接可以请求多个数据.

具体的通信过程,首先要明确 HTTP2.0 协议以下三个重要概念:

  1. 数据流(Stream):客户端和服务器之间传输数据的通道(一个连接中可以有多个数据流).
  2. 消息(message):一个消息中就包含了多个帧.
  3. 帧(frame):就是一些具体的请求头,请求体信息.

如下图:

Ps:

  1. 数据流的优先级:可以通过权重的方式设置的,用来限制的不同流的传输顺序.
  2. 流控效果:client 发送数太快了,server 处理不过来,就会通知 client 暂停数据的发送.

1.3、Protocol Buffers(Protobuf)

1.3.1、protobuf 是什么

protobuf 是一种与编程语言无关,与具体平台无关(任意操作系统)的序列化工具,自定义了中间语言(IDL),使得数据在 client 和 server 中进行 RPC 传输.

Ps:protobuf 有两个版本(proto2 和 proto3),主流应用都是 proto3.

1.3.2、安装 Protobuf 编译器

protobuf 安装编译器的目的就是为了把 protobuf 的 IDL 语言,转化成某一种开发语言,例如 Java.

a)下载地址:Releases · protocolbuffers/protobuf · GitHub

新版没有提供 windows 版本的安装包,可以去老版本找到,例如 Protocol Buffers v23.1

b)下载好后解压,配置环境变量 path

c)打开终端,输入 protoc --version,检查是否配置成功(查看版本)

1.3.3、protobuf 语法

a)文件格式:文件都是以 proto 为后缀,例如 UserService.proto、OrderService.proto.

b)版本设定:使用 proto3 即可

syntax = "proto3";

c)注释:// 表示单行注释,/* */ 表示多行注释.

d)Java 语言相关

//protobuf 生成的 Java 代码,是一个源文件还是多个?false 表示一个(一般开发就用 false)
option java_multiple_files = false;

//指定 protobuf 生成的类,放置在哪个包中
option java_package = "com.cyk";

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

e)逻辑包:protobuf 对文件内容的管理(作为 Java 工程师,可以不用逻辑包,用 Java 包就够了,逻辑包了解就行)

package xxx

f)导入:假设有 A.proto 和 B.proto 文件,现在需要在 B.proto 文件中引入 A.proto 文件的内容,就需要在 B.proto 文件中导入 A.proto.

// 在 B.proto 文件中导入 A.proto 文件
import xxx/A.proto

g)枚举:枚举值必须是从 0 开始.

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

h)数据类型:就是消息中定义的数据类型(我们主要关心 .proto 对应的 Java 类型).

以下列表来自官网:Language Guide (proto 3) | Protocol Buffers Documentation

.proto TypeC++ TypeJava/Kotlin Type[1]Python Type[3]Go TypeRuby TypeC# TypePHP TypeDart Type
doubledoubledoublefloatfloat64Floatdoublefloatdouble
floatfloatfloatfloatfloat32Floatfloatfloatdouble
int32int32intintint32Fixnum or Bignum (as required)intintegerint
int64int64longint/long[4]int64Bignumlonginteger/string[6]Int64
uint32uint32int[2]int/long[4]uint32Fixnum or Bignum (as required)uintintegerint
uint64uint64long[2]int/long[4]uint64Bignumulonginteger/string[6]Int64
sint32int32intintint32Fixnum or Bignum (as required)intintegerint
sint64int64longint/long[4]int64Bignumlonginteger/string[6]Int64
fixed32uint32int[2]int/long[4]uint32Fixnum or Bignum (as required)uintintegerint
fixed64uint64long[2]int/long[4]uint64Bignumulonginteger/string[6]Int64
sfixed32int32intintint32Fixnum or Bignum (as required)intintegerint
sfixed64int64longint/long[4]int64Bignumlonginteger/string[6]Int64
boolboolbooleanboolboolTrueClass/FalseClassboolbooleanbool
stringstringStringstr/unicode[5]stringString (UTF-8)stringstringString
bytesstringByteStringstr (Python 2)
bytes (Python 3)
[]byteString (ASCII-8BIT)ByteStringstringList

i)消息(Message):定义了客户端和服务器一次请求和相应的具体格式

//1.Ps: 编号范围是[1, 2^29-1],但是 19000~19999 不能使用,因为他是 protobuf 自己保留的
message LoginRequest {
   string username = 1;
   string password = 2;
   int32 age = 3;
}

//2.singular: 表示这个字段的值只能有 0 个或 1 个,也就是 null 或者是一个具体的值
//repeated: 表示 Java 中的 List 类型
message LoginResponse {
  string content = 1;
  repeated string status = 2;
}

//3.消息可以嵌套
message LogoutRequest {
  message User {
    int64 userId = 1;
    string username = 2;
  }

  string aaa = 1;
  string bbb = 2;
  User user = 3;
}

//4.可以使用其他消息的属性
message Test1Message {
  string aaa = 1;
  LogoutRequest.User bbb = 2;
}

//5.oneof 表示其中一个(实际开发中用的很少)
message Test2Message {
  oneof test_oneof {
    string aaa = 1;
    string bbb = 2;
  }
}

j)服务:用来定义服务接口,一个接口中可以有多个服务方法(gRPC 的 4 个服务方式下一章再展开讲~).

Ps:自定义接口名 不可以和 option java_outer_classname = "xxx" 这里配置的生成类名xxx一致!否则报错!

语法如下:

service 自定义接口名 {
  rpc 自定义方法名(参数类型) returns(返回值类型) {}
  //......
}

例如: 

message LoginRequest {
   string username = 1;
   string password = 2;
   int32 age = 3;
}
message LoginResponse {
  string content = 1;
  repeated string status = 2;
}


service UserService {
  rpc login(LoginRequest) returns(LoginResponse) {}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/298981.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C# Entity Framework 中不同的数据的加载方式

延迟加载 延迟加载是指在访问导航属性时,Entity Framework 会自动查询数据库并加载相关数据。这种方式在我们需要访问导航属性时比较方便,因为我们无需手动加载相关数据,而且只会在需要时才会进行查询,从而减少了不必要的开销。但…

基于商品列表的拖拽排序后端实现

目录 一:实现思路 二:实现步骤 二:实现代码 三:注意点 一:实现思路 后台实现拖拽排序通常需要与前端进行配合,对商品的列表拖拽排序,前端需要告诉后端拖拽的元素和拖动的位置。 这里我们假…

【远程计算机,这可能是由于 Credssp 加客数据库修正】解决方案

1、winR打开运行窗口 输入gpedit.msc命令,若找不到,可以进行如下文件编辑格式为cmd echo offpushd "%~dp0"dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum >List.txtdir /b C:\Win…

Linux stm32串口下载程序

一、工具 使用stm32flash进行串口下载 二、stm32flash安装 sudo apt-get install stm32flash 三、查看串口设备名称 先拔掉串口运行下面指令,获得所有设备名称,插上串口再运行一次,新增的就是串口设备名称,记住串口设备名称,以…

Linux目录结构及路径描述方式

1.Linux目录结构 Linux与Windows不同,Linux没有盘符这个概念, 只有一个根目录 /, 所有文件都在它下面 2.Linux路径的描述方式 在Linux系统中,路径之间的层级关系,使用:/ 来表示 在Windows系统中,路径之间的层级关系…

echarts图表会残留上一条数据的折线 setOption参数的第二个坑

记一下小坑 因为我的echarts图表的 series 是循环渲染上去的 所以他可能会有一条 或多条 我展示完多条的图表后 关闭 打开单条数据的图表 发现 他会残留上一个图表的数据 显示多条 之前我还以为是后端返回错了 但是log打印和查看请求数据 确实发现是我这边的问题 原因&#…

第二百四十三回 再分享一个Json工具

文章目录 1. 概念介绍2. 分析与比较2.1 分析问题2.2 比较差异 3. 使用方法4. 内容总结 我们在上一章回中介绍了"分享三个使用TextField的细节"相关的内容,本章回中将再 分享一个Json插件.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我…

系列二、GitHub中的Alpha、Beta、RC、GA、Release等各个版本

一、GitHub中的Alpha、Beta、RC、GA 1.1、概述 1.2、参考 https://www.cnblogs.com/huzhengyu/p/13905129.html

软件测试/测试开发丨Pytest结合数据驱动

安装yaml pip install pyyaml pytest结合数据驱动yaml 工程目录结构 数据准备 读取excel文件 openpyxl库的安装 openpyxl库的操作 pytest结合csv实现数据驱动 csv文件介绍 pytest结合json实现数据驱动 最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的&…

第15课 利用openCV实现人脸识别

这节课,我们再来看一个简单且实用的例子:人脸识别。这个小例子可以让你进一步领略openCV的强悍。 1.复制demo14并改名为demo15。 2.修改capImg函数: int fmle::capImg() {// 加载人脸检测分类器cv::CascadeClassifier faceCascade;faceCas…

RT_Thread 调试笔记:时间相关,时钟管理函数,延时,定时器、 毫秒转换为时分秒 等

说明:记录日常使用 RT_Thread 开发时做的笔记。 持续更新中,欢迎收藏。 1. 延时函数 1. us延时函数 rt_hw_us_delay(rt_uint32_t us);//输如数据是us rt_hw_us_delay(200);//输入数据是us 2. ms延时函数 rt_thread_mdelay(1000);//输入数据是ms 2…

Java:IO流详解

文章目录 基础流1、IO概述1.1 什么是IO1.2 IO的分类1.3 顶级父类们 2、字节流2.1 一切皆为字节2.2 字节输出流 OutputStream2.3 FileOutputStream类2.3.1 构造方法2.3.2 写出字节数据2.3.3 数据追加续写2.3.4 写出换行 2.4 字节输入流 InputStream2.5 FileInputStream类2.5.1 构…

特征工程筛选重要变量

特征筛选主要分为3个方法:过滤法、嵌入法(经典的一些树模型比如xgboost)、包裹法(经典的RFECV,RFE递归特征消除法) 过滤法更快速,但更粗糙。 包装法和嵌入法更精确,比较适合具体到算…

自动驾驶:低阶可部署的单目测距算法-基于YOLO与透视变换

一、开发环境 部署平台:英伟达的Jetson Nano 环境:Linux ROS 语言:C 设备:1920*1080像素的摄像头、开发板。 模型:yolo-v8s 二、单目测距实现思路 0、标定相机和车辆(假设已经标定完成) 1、通…

Linux习题6

解析:排序必须得是rwx,所以B不对 解析: /etc/resolv.conf:是DNS配置文件。在网卡配置文件中进行配置,默认情况下,网卡配置文件DNS优于/etc/resolv.conf。 /etc/hostname:在centos7,配置主机名…

【ZooKeeper高手实战】ZAB协议:ZooKeeper分布式一致性的基石

🌈🌈🌈🌈🌈🌈🌈🌈 欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术 的推送 发送 资料 可领取 深入理…

小白入门基础 - Restful

一:REST与RESTful: REST:表现层状态转移,资源在网络中以某种形式进行状态转移。 RESTful是基于REST理念的一套开发风格,是具体的开发规则。 服务器端只返回数据,以json或者xml的格式。 RESTful开发规范&a…

DockerUI本地如何部署并结合内网穿透实现远程访问管理界面

文章目录 前言1. 安装部署DockerUI2. 安装cpolar内网穿透3. 配置DockerUI公网访问地址4. 公网远程访问DockerUI5. 固定DockerUI公网地址 前言 DockerUI是一个docker容器镜像的可视化图形化管理工具。DockerUI可以用来轻松构建、管理和维护docker环境。它是完全开源且免费的。基…

项目管理进阶之PDCA

前言 项目管理进阶系列,今天开始发布第一篇喽。 博主其实一直在构思,如何开启这个系列,但是我们通常项目管理讲的“五大过程十大领域”,往往太书面了。因此尝试从中抓取几个核心,以供有志之士参考。 那么&#xff0c…

C++——简介、Hello World、变量常量、数据类型

个人简介 👀个人主页: 前端杂货铺 🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…