gRPC-shop: 初识protobuf(二)

简介: gRPC-shop: 初识protobuf(二)

上一篇gRPC-shop:什么是 gRPC(一)主要介绍了 gRPC 基础概念,gRPC 采用 Protobuf 作为它的序列化协议格式,那么这篇文章我们简单介绍一下 Protobuf


Protobuf 是什么


Protobuf全称是Protocal buffers平时我们都会简称为pb下文就使用pb代称了。

官网中对pb的完整定义如下:

Protocol buffers are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages.

简单的说pb是一种与语言、平台无关,可扩展的序列化数据格式它的定位类似于JSONXML但是比他们更小、更快、更简单

对于开发者来说,我们只需要定义proto文件然后使用对应的IDL编译器把.proto文件编译成对应语言的代码即可

从某个角度来看.proto文件就是接口。里面包含了接口方法、入参、出参


如何使用


环境安装可以看这篇[1]

来看一个简单的示例我们创建一个order.proto文件,内容如下:


1668508207409.jpg


逐行解释

pb有两个版本,默认版本是proto2如果要使用proto3我们就得在非空非注释的第一行代码中使用syntax = "proto3";声明版本

option表示可选项配置。有些选项是文件级别的,需要在一个文件的顶级作用域定义,比如上面的option go_package = "order";

go_package选项,定义的值,就是把pb文件编译生成Go代码后文件的package名。这样其他生成的Go代码就可以通过关键字import使用到这个包

你可能还会在.proto文件中看到类似package xxx这样的, 比如


1668508225380.jpg


package主要用来解决不同的pb文件存在相同消息类型名称之间的冲突。比如a.proto有一个Common messageb.proto也有一个Common message此时需要通过package来做区分


packagego_package有什么关系吗

There is no correlation between the Go import path and the package specifier in the .proto file. The latter is only relevant to the protobuf namespace, while the former is only relevant to the Go namespace. Also, there is no correlation between the Go import path and the .proto import path.

没有关系

package只和pb空间有关go_package前面解释过了,和Goimport包有关,他们两者,本质上不是一个层面的。

接着我们定义了一个Order的消息message类型,定义消息类型是使用关键字message定义的

Order定义了四个字段,对应stringuint32以及bool字段类型

消息类型中字段定义的格式为


1668508265114.jpg


默认情况下,每个字段最前面的修饰符为singular一般省略不写

假设一个主订单下有多个子订单,我们可以如何定义?


1668508287407.jpg


我们新定义了一个OrderItem子订单的消息类型。然后在Order中,我们使用了OrderItem作为items字段的类型值

repeated是另一种修饰符,表示允许字段重复。上面的场景即一个订单有多个子订单的概念。

编译成Go代码items会变成slice类型


其他类型就不一一介绍,更多的类型可以查看这:Protocol Buffers v3.0.0[2]

接着我们通过命令编译(确保工具已装)生成Go相关的代码,执行如下命令


1668508299608.jpg


--proto_path指定要编译的源码的搜索路径,上面的.表示当前目录。如果不指定--proto_path的话,默认为pwd。所以上面我们也可以省略成这样


1668508309767.jpg


--go_out参数告知protoc编译器去加载对应的protoc-gen-go工具且指定编译生成Go代码后保存位置。当然如果是生成php代码那就是--php_out对应的语言对应--xx_out

最后的*.proto表示搜索当前目录下所有.proto文件

那么整句命令行意思就是:编译当前目录下所有.proto文件, 把生成的Go代码存放到当前目录。


上面的命令执行后,当前目录下多了一个order.pb.go文件。生成的数据结构:


1668508321153.jpg


可以看到生成的主订单结构中Items是一个切片类型。同时生成的还有一些Getxxx方法方便读取字段值

等等,接口呢?

message有了,现在我们可以在.proto文件定义RPC服务接口了


1668508335570.jpg


我们定义了一个 OrderService的服务,提供了一个GetOrderList的接口,它的入参是OrderListReq返回类型是OrderListResp是不是很像我们平常定义的函数。

和平常自定义函数的不同在于,可以自定义无入参出参的函数,而在pb中接口必须携带参数,否则编译的时候会报,

Expected type name

针对不需要参数的情况,我们一般会定义一个空message类型或者传入google.protobuf.Empty传入google.protobuf.Empty不好点在于不易扩展,万一这个接口要参数了呢。


service定义完毕,再次执行上述命令,你会发现,重新生成的order.pb.go文件并没有变化。这是因为RPC框架很多protoc编译器并不知道给我们生成哪个RPC框架的代码。

protoc-gen-go内部已经集成了一个名为gRPC的插件,所以我们可以通过命令行参数--go-grpc_out生成gRPC代码


1668508349229.jpg


然后你就发现这个错误


1668508362611.jpg


我们需要改动option go_package = ".;order"option go_package = "./;order"

再次执行,多出了一个order_grpc.pb.go文件。里面就能看到grpc客户端和服务端的api服务


1668508376743.jpg


总结

这篇主要介绍了pb一些基础的知识,包括定义messageservice以及通过protoc-gen-go生成对应的Go代码gRPC代码关于 protoc命令,后面有必要再单独写一篇文章。

下一篇,通过生成的Go代码,完成gRPC通信,然后正式步入主题


参考


相关文章
|
数据可视化 BI
探索ERP系统的移动端应用与移动办公解决方案
探索ERP系统的移动端应用与移动办公解决方案
528 2
|
JavaScript 前端开发
【vue】 接口返回的preview是张图片,前端如何渲染
【vue】 接口返回的preview是张图片,前端如何渲染
403 0
|
10月前
|
Web App开发 安全 网络协议
多域名 SSL 证书是什么? 多域名 SSL 证书申请流程
多域名SSL证书是保护多个网站时的高效选择,它使得单个证书能够保护多个域名(网站)。这种证书通过在用户的Web浏览器和托管网站的服务器之间建立安全的加密连接,确保了敏感信息(包括登录凭证、信用卡信息和其他个人数据)的安全传输。
741 1
|
SQL 存储 分布式计算
Hive学习---6、文件格式和压缩
Hive学习---6、文件格式和压缩
Hive学习---6、文件格式和压缩
|
Ubuntu 网络安全 数据安全/隐私保护
ubuntu server连接wifi教程
本文提供了一个简化Ubuntu Server在Raspberry Pi系统上配置过程的脚本"config_ubuntu_server",包括自动和手动两种方法来设置root权限、SSH配置,并连接WiFi,同时支持无密码SSH访问,适合初学者和高级用户。
464 3
|
机器学习/深度学习 人工智能 TensorFlow
机器学习项目实战:使用Python实现图像识别
在AI时代,Python借助TensorFlow和Keras实现图像识别,尤其在监控、驾驶、医疗等领域有广泛应用。本文通过构建CNN模型识别MNIST手写数字,展示图像识别流程:安装库→加载预处理数据→构建模型→训练→评估。简单项目为深度学习入门提供基础,为进一步探索复杂场景打下基础。
1273 5
|
存储 SQL 分布式计算
企业数仓架构设计实践
本文是一位数据架构师在设计企业级数据仓库架构时的思考与实践经验分享。从理论基础(数据仓库概念、Lambda架构、Kimball与Inmon方法)到工具选型(如Hadoop、Hive、Spark、Airflow、Tableau等),再到实践过程(需求调研、架构设计、技术选型落地、数据模型设计、测试迭代及用户培训),全面阐述了数仓建设的各个环节。强调了业务理解与技术结合的重要性,并指出数仓建设是一个持续优化、适应业务发展变化的过程。
642 3
|
存储 缓存 Unix
【进程IO】详细讲解文件描述符fd
【进程IO】详细讲解文件描述符fd
|
开发者
「开放麦」这些开放平台术语你都认识吗?
「开放麦」这些开放平台术语你都认识吗?
282 11
|
JavaScript 前端开发
植物大战僵尸Javascript版web游戏源码
植物大战僵尸Javascript版web游戏源码,非常强大,1比1还原电脑版植物大战僵尸游戏,带背景音乐,玩法和原版一模一样。
557 2