这里写目录标题
RPC
什么是RPC
RPC指远程过程调用(Remote Procedure Call)。允许运行于一台计算机的程序调用另一台计算机的子程序,并且调用起来像调用本地函数一样简单。
例如:服务器A上运行的应用C,想要调用服务器B上运行的应用D,就可以很方便地通过RPC进行调用,跟调用一个本地函数一样简单。
RPC的原理
图片来自b站up主弯曲的一条虫给热爱gRPC的你!神奇代码在哪里Go实战#9:gRPC
很不错的教学视频,推荐大家观看!
RPC服务的调用过程如下:
1、客户端client
调用client stub
,这是一次本地调用
2、client stub
接下来会将客户端client
传入的消息编码成统一的格式
3、然后由rpc client
将消息发送给rpc server
4、rpc server
收到由rpc client
传来的消息
5、之后server
会将收到的消息进行解码
6、然后通过路由找到对应的接口进行处理
7、最后将结果返回给客户端client
stub,中文名为桩代码,负责为上层应用处理rpc
调用中的数据编解码,收发请求等脏活累活,而客户端在调用rpc服务时就好像本地调用了stub
的一个子函数一样,不需要去过多地关注其他过程。
IDL
IDL(Interface Definition Language),接口描述语言。
IDL通过一种中立的方式来描述接口,使得在不同平台上运行的对象和用不同语言编写的程序可以相互通信交流。比如,一个组件用C++写成,另一个组件用Go写成,IDL可以为这两个组件提供通用的消息中间体。
在RPC中,Protobuf是一种常用的IDL。
常见的RPC框架
- Hessian
- Montan
- rpcx
- gRPC
- Thrift
- Dubbo
- Dubbox
- Spring Cloud
Protobuf
介绍
Protocol Buffers是一种语言无关、平台无关,可拓展的序列化结构化数据的方法,常用于通信协议,数据存储等等。
相较于JSON、XML,它更小、更快,因此也更受开发人员的青睐。
pb是Protobuf的简称。
安装
Protobuf编译器
1、下载protobuf并编译安装
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.20.0-rc1/protobuf-all-3.20.0-rc-1.zip
unzip protobuf-all-3.20.0-rc-1.zip
cd protobuf-3.20.0-rc-1/
./configure
make
make install
2、通过go get
安装
go get google.golang.org/protobuf
验证是否安装成功
protoc --version
libprotoc 3.20.0-rc1 # 输出版本号证明安装成功
Protobuf编译器插件:protocol-gen-go
protoc-gen-go
增强了protoc编译器,使其知道如何为给定.proto
文件生成go代码。
protoc-gen-go
包含在google.golang.org/protobuf
包中,可直接安装google.golang.org/protobuf
包一步到位,无需单独安装。
单独安装protoc-gen-go
可以通过 go get
来安装,需要Go v1.16
或更高版本
go get -u github.com/golang/protobuf/protoc-gen-go
Protobuf运行时库
该 protobuf
模块包含一组 Go 包,这些包为 Go 中 protobufs 的运行时提供了一些API。这提供了一组 定义消息是什么的接口, 以及以各种格式(例如, wire、 JSON和 text)序列化消息的功能。
该运行时库包含在google.golang.org/protobuf
中,google.golang.org/protobuf
由两个部分组成:protocol-gen-go
和此运行时库。
通过 go get
安装:
go get google.golang.org/protobuf
Protobuf文件语法
Protobuf数据结构定义的简单示例:
syntax = "proto3";
option go_package = "../stub";
service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
解释:
1、Protobuf语法版本声明
syntax = "proto3";
2、声明生成源代码时作为Go的包名
option go_package = "../stub";
包名中.
在生成后的Go包名中会转换为_
。
如果没有此声明的话,编译时会报错:
Missing 'go_package' option in "test.proto"
3、RPC服务定义
service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
4、消息定义
消息中的每一个字段包含三个属性:类型、字段名称、字段编号。
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
以上是Protobuf语法的简单介绍,更详细的语法请见官方文档: Protocel Buffers
此外,官方还说明了Protobuf的一些规范:规范指南
数据类型
.proto Type | C++ Type | Java Type | Go Type | PHP Type |
---|---|---|---|---|
double | double | double | float64 | float |
float | float | float | float32 | float |
int32 | int32 | int | int32 | integer |
int64 | int64 | long | int64 | integer/string |
uint32 | uint32 | int | uint32 | integer |
uint64 | uint64 | long | uint64 | integer/string |
sint32 | int32 | int | int32 | integer |
sint64 | int64 | long | int64 | integer/string |
fixed32 | uint32 | int | uint32 | integer |
fixed64 | uint64 | long | uint64 | integer/string |
sfixed32 | int32 | int | int32 | integer |
sfixed64 | int64 | long | int64 | integer/string |
bool | bool | boolean | bool | boolean |
string | string | String | string | string |
bytes | string | ByteString | []byte | string |
protoc命令行
查看protoc命令行帮助
protoc --help
常用参数
-I[PATH], --peoro_path=[PATH]
# 指定 import 搜索的目录,可指定多个;将按顺序搜索目录。如果未给出,则使用当前工作目录。若在这些目录中找不到,则将检查描述符中的--descriptor_set_以查找所需的原型文件。
--go_out=[PATH]
# 生成go语言的桩代码,并放到 PATH 目录中
--go-opt
# 指定参数,比如--go_opt=paths=source_relative就是表明生成文件输出使用相对路径。
更详细protoc
语法可见官方文档:https://developers.google.com/protocol-buffers/docs/reference/go-generated
gRPC
介绍
gRPC是一个高性能、开源和通用的RPC框架,面向移动和HTTP 2.0设计
gRPC架构概览
多语言支持
- C++
- C#
- Dart
- Go
- Java
- Node.js
- Objective-C
- PHP
- Python
- Ruby
特点
1、基于HTTP 2.0
2、采用Protobuf进行序列化
3、客户端、服务端基于同一份IDL
4、移动网络的良好支持
5、多语言支持
安装
通过go get
安装:
go get google.golang.org/grpc
gRPC的4中通信方式
Unary 一元方式
说白了就是请求响应模式,一次请求一次响应。
Client-side streaming 客户端流式
客户端以类似流的形式不断请求服务端,而服务端在请求结束之后,只返回一个响应回去。
Server-side streaming 服务端流式
客户端只请求一次服务端,然后服务端以类似流的形式不断把响应传给服务端。
Bidirectional streaming 双向流式
客户端和服务端均以流的形式互相请求和响应。
gRPC中protobuf文件的编写
在gRPC中,一般protobuf文件中主要编写两部分信息,一个是message,一个是service。
代码桩生成命令
使用--go-grpc_out
:
--go-grpc_out=[PATH]
# 生成grpc的桩代码,并放到 PATH 目录中
也可以这样,proto
文件指定了RPC
服务,protoc-gen-go
可以生成与grpc
相兼容的代码,我们仅需要将plugins=grpc
参数传递给--go_out
,就可以达到这个目的。不过目前此方法在新版本中已弃用。
--go_out=plugins=grpc:[PATH]
# plugins=plugin1+plugin2:指定要加载的子插件列表
例子:
protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative route.proto
# --go_out=[PATH]:生成与golang相兼容的代码文件