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) {}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构-怀化学院期末题

希尔排序 题目&#xff1a; 利用希尔排序算法实现线性表的排序。希尔排序是根据给定的增量序列将线性表分隔成某个“增量”的记录组成一个子序例&#xff0c;在子序列中采用直接插入排序完成。 输入 第一行为元素个数n(1<n<1000)&#xff0c;第二行为n个元素值(整数)&am…

【C++】带你学会使用C++线程库thread、原子库atomic、互斥量库mutex、条件变量库condition_variable

C线程相关知识讲解 前言正式开始C官方为啥要提供线程库thread构造函数代码演示this_threadget_id()yield()sleep_until和sleep_for mutex构造函数lock和unlock上锁全局锁局部锁lambda表达式 try_lock 其他锁时间锁递归版本专用锁recursive_mutex 锁的异常处理lock_guardunique_…

Linux_CentOS_7.9_Oracle11gr2配置数据库及监听服务自启动多方案实操之简易记录

前言: 作为运维保障,都无法准确预估硬件宕机的突发阶段,其生产数据实时在产出,那作为dba数据库服务以及相关Listener的其重要性、必要性就突显而出。这里拿虚拟机试验做个配置记录,便于大家学习参考。 实现方法一: 环境变量值::$ORACLE_HOME= /data/oracle/product/1…

逆向一个Go程序

前奏 事先声明&#xff0c;自导自演&#xff0c;纯属为了演示基本的逆向思维 用Go写一段模拟登录的代码&#xff1a; package mainimport ("fmt" )func main() {pass : ""fmt.Print("input password:")fmt.Scan(&pass)if pass "hel…

包管理

moment —解析,校验,操作日期的第三方包 在项目中安装和使用包 1. 安装npm install 包的完整名称---可以简写为npm i 完整包的名称2. 导入包require(包名称)3. 查看官方文档初次装包完成后,在项目文件夹下多了一个node_modules文件夹和package-lock.json的配置文件. node_modu…

【极客日常】慢查询的风险治理思路

在线上环境运维过程中&#xff0c;我们通常需要治理慢查询的风险。慢查询会引起DB性能问题&#xff0c;并且当线上环境流量较大的情况下&#xff0c;就会出现因大量慢查询堆积导致DB被打挂的情况。因此&#xff0c;本篇文章分享一下慢查询的风险治理思路。 首先&#xff0c;我…

Matlab二维绘图

低级绘图命令line 有什么点就点哪里&#xff0c;然后连起来&#xff0c;没什么细节&#xff0c;不光滑&#xff0c;所以基本不会用到。 x0:0.2*pi:2*pi; ysin(x); line(x,y);%画一条sin函数线 line([-5,5],[2,2]);%画一条水平线 line([5,5],[0,2]);%画一条竖线 高级绘图命令…

一文搞懂MCU RAM的分配

一文搞懂MCU RAM的分配 文章目录 一文搞懂MCU RAM的分配1. 前言2. 数据段含义2.1 Program Size解析 3. 局部变量、全局变量、常量如何占用 RAM?3.1 栈大小Stack_Size 与 堆大小Heap_Size3.2 验证栈大小设置&#xff0c;对程序编译的影响3.3 验证局部变量RAM分配3.4 验证全局变…

Mac系统安装PicGo时打开报错:文件已损坏

目录 一、前言二、解决方案三、结尾 一、前言 我们在安装某些第三方开发者开发的应用时&#xff0c;无法在 Mac 上运行&#xff0c;提示已经损坏&#xff0c;报以下错误&#xff1a;Mac系统安装PicGo时打开报错&#xff1a;文件已损坏&#xff0c;您应该将它移到废纸篓 二、解决…

LeetCode 2807.在链表中插入最大公约数

【LetMeFly】2807.在链表中插入最大公约数 力扣题目链接&#xff1a;https://leetcode.cn/problems/insert-greatest-common-divisors-in-linked-list/ 给你一个链表的头 head &#xff0c;每个结点包含一个整数值。 在相邻结点之间&#xff0c;请你插入一个新的结点&#x…

DQL命令查询数据(三)

本课目标 掌握MySQL的多表查询 SQL语句的综合应用 多表连接查询 通过各个表之间共同列的关联性&#xff08;例如&#xff1a;外键&#xff09;来查询的 分类&#xff1a; 内连接(INNER JOIN) &#xff0c;可简写为 JOIN&#xff1b;左外连接(LEFT OUTER JOIN)&#xff0c;…

Java技术栈 —— Hadoop入门(一)

Java技术栈 —— Hadoop入门&#xff08;一&#xff09; 一、Hadoop第一印象二、安装Hadoop三、Hadoop解析3.1 Hadoop生态介绍3.1.1 MapReduce - 核心组件3.1.2 HDFS - 核心组件3.1.3 YARN - 核心组件3.1.4 其它组件3.1.4.1 HBase3.1.4.2 Hive3.1.4.3 Spark 一、Hadoop第一印象…

【Project】TPC-Online Module (manuscript_2024-01-07)

PRD正文 一、概述 本模块实现隧道点云数据的线上汇总和可视化。用户可以通过注册和登录功能进行身份验证&#xff0c;然后上传原始隧道点云数据和经过处理的数据到后台服务器。该模块提供数据查询、筛选和可视化等操作&#xff0c;同时支持对指定里程的分段显示和点云颜色更改…

小游戏实战丨基于PyGame的消消乐小游戏

文章目录 写在前面PyGame消消乐注意事项系列文章写在后面 写在前面 本期内容&#xff1a;基于pygame实现喜羊羊与灰太狼版消消乐小游戏 下载地址&#xff1a;https://download.csdn.net/download/m0_68111267/88700193 实验环境 python3.11及以上pycharmpygame 安装pygame…

回溯算法part01 算法

回溯算法part01 今日内容&#xff1a; ● 理论基础 ● 77. 组合 1.LeetCode77. 组合 https://leetcode.cn/problems/combinations/ 模板 //回溯算法模板void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择&#xff1a;本层集合中元素&#xff08;树中节…

西电期末1027.判断同构数

一.题目 二.分析与思路 不用把他转成字符串再转成数字之类的&#xff0c;用数学解决就好&#xff01;找出一个数的最后位就是将其对求余啊&#xff0c;找一个数有几位以前也有过啊&#xff0c;那不就过了嘛&#xff01; 三.代码实现 #include<bits/stdc.h>//万能头 in…

模板元编程简介

从引入 template 关键字开始&#xff0c;C里就出现了泛型编程&#xff0c;而又泛型编程衍生出的模板元编程&#xff08;template meta_programming&#xff0c;简称“元编程”&#xff09;则是众多编程范式中最复杂、最强大和最具有权威的一种。所谓“元编程”——metaprogramm…

Keil C51的编译器限制

编译器限制 Cx51 编译器体现了下面列出的一些已知限制。在大多数情况下&#xff0c;对 C 语言的组件没有限制;例如&#xff0c;您可以在 switch 块中指定无限数量的符号或 case 语句。如果有足够的地址空间&#xff0c;则可以定义数千个符号。 最多支持对任何标准数据类型的 …

二叉树的经典算法(算法村第八关青铜挑战)

二叉树里的双指针 所谓的双指针就是定义了两个变量&#xff0c;在二叉树中有需要至少定义两个变量才能解决问题。这两个指针可能针对一棵树&#xff0c;也可能针对两棵树&#xff0c;姑且也称之为“双指针”。这些问题一般与对称、反转和合并等类型题相关。 判断两棵树是否相…

Python:tqdm模块详解

tqdm 是一个用于在 Python 中显示进度条的模块&#xff0c;用于在循环或迭代过程中展示任务的进度。 1. 安装 首先&#xff0c;你可以通过 pip 安装 tqdm 模块&#xff1a; pip install tqdm2. 基本使用方法 在 Python 中使用 tqdm &#xff0c;只需将你的迭代对象传递给 tqd…