【Go】gRPC + Protobuf 学习笔记

这里写目录标题

    • RPC
      • 什么是RPC
      • RPC的原理
      • IDL
      • 常见的RPC框架
    • Protobuf
      • 介绍
      • 安装
        • Protobuf编译器
        • Protobuf编译器插件:protocol-gen-go
        • Protobuf运行时库
      • Protobuf文件语法
      • 数据类型
      • protoc命令行
    • gRPC
      • 介绍
      • gRPC架构概览
      • 多语言支持
      • 特点
      • 安装
      • gRPC的4中通信方式
        • Unary 一元方式
        • Client-side streaming 客户端流式
        • Server-side streaming 服务端流式
        • Bidirectional streaming 双向流式
      • gRPC中protobuf文件的编写
      • 代码桩生成命令

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

【Go】gRPC + Protobuf 学习笔记_第1张图片

介绍

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

【Go】gRPC + Protobuf 学习笔记_第2张图片

介绍

gRPC是一个高性能开源通用的RPC框架,面向移动和HTTP 2.0设计

官方文档:https://grpc.io/docs/

gRPC架构概览

【Go】gRPC + Protobuf 学习笔记_第3张图片

多语言支持

  • 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相兼容的代码文件

你可能感兴趣的:(GO,golang,rpc)