Protobuf 的介绍与使用(入门级)

背景


在移动互联网时代,手机流量、电量是最为有限的资源,而移动端的即时通讯应用无疑必须得直面这两点。

解决流量过大的基本方法就是使用高度压缩的通信协议,而数据压缩后流量减小带来的自然结果也就是省电:因为大数据量的传输必然需要更久的网络操作、数据序列化及反序列化操作,这些都是电量消耗过快的根源。

当前即时通讯应用中最热门的通信协议无疑就是Google的Protobuf了,基于它的优秀表现,微信和手机QQ这样的主流IM应用也早已在使用它。本文将详细介绍Protobuf的使用、原理等。

Protobuf 介绍


Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准,目前已经正在使用的有超过 48,162 种报文格式定义和超过 12,183 个 .proto 文件。他们用于 RPC 系统和持续数据存储系统。

Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了 C++、Java、Python 三种语言的 API(即时通讯网注:Protobuf官方工程主页上显示的已支持的开发语言多达10种,分别有:C++、Java、Python、Objective-C、C#、JavaNano、JavaScript、Ruby、Go、PHP,基本上主流的语言都已支持,详见工程主页:https://github.com/52im/protobuf)。

或许您和我一样,在第一次看完这些介绍后还是不明白 Protobuf 究竟是什么,那么我想一个简单的例子应该比较有助于理解它。

Protobuf 安装


安装 Protobuf

编译安装 protobuf 的编译器 protoc

wget https://github.com/google/protobuf/releases/download/v3.6.1/protobuf-all-3.6.1.tar.gztar zxvf protobuf-all-3.6.1.tar.gzcd protobuf-3.6.1// /usr/local/ 为安装路径
./configure --prefix=/usr/local/# 要编译很久
sudo make -j`nproc`
sudo make check
sudo make install// 检查安装结果
protoc --version

安装结果:

注:protobuf 的静态库被安装到了 /usr/local/lib 中,如果在执行 protoc --version 时,报错:protoc: error while loading shared libraries: libprotoc.so.17: cannot open shared object file: No such file or directory;则只需将 /usr/local/lib 添加到环境变量即可!

添加命令如下:

// 该添加只在当前窗口有效
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

安装 protoc-gen-go 插件

使用 Go 的包管理工具 go install 来安装 protobuf 的 Go 插件。这个插件现在是作为一个独立的模块发布的,而不是 google.golang.org/protobuf 包的一部分,因此需单独安装。

从 Go 1.11 开始,Go 引入了模块作为官方的依赖管理工具,并逐渐替代了 GOPATH 模式。在 Go 模块模式下,Go 项目可以有自己独立的依赖管理,不再严格依赖于全局的 GOPATH。

在 Go 模块模式下,可能不会直接操作 $GOBIN 环境变量,因为 go install 命令会自动处理二进制文件的安装位置。但是,如果想要自定义安装位置,可以设置 $GOBIN 环境变量。例如:

// 指定 protoc-gen-go 的安装位置
export GOBIN=/usr/local/go/bin// 安装 protoc-gen-go
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest

注:把 .proto 文件编译成 .go 文件依赖 protoc-gen-go;

Protobuf 使用


创建 .proto 文件

创建 metadata.proto 文件

syntax = "proto3";
package message;option go_package = "/data/etcd_test/src/message";message Metadata {string Name = 1;string DBName = 2;string Type = 3;int64 ShardMethod = 4;string ShardKey = 5;int64 ShardCount = 6;string Groups = 7;string RangeInfo = 8;
}

注:

  • go_package 用于指定生成的GO代码应该使用哪个包名,并且(可选地)指定生成代码的输出目录
  • 字段后面的数字在序列化过程中唯一标识字段,这些标识符在消息定义中是唯一的,并且在整个.proto文件中应该是唯一的

编译.proto 文件

protoc --go_out=. --go_opt=paths=source_relative ./src/message/metadata.proto

注:

  • --go_out=. 告诉 protoc 编译器生成 Go 代码,并将输出放在当前目录(.表示当前目录)
  • --go_opt=paths=source_relative 是一个选项,它告诉 protoc-gen-go 生成代码时使用相对于 .proto 文件的路径,这在 Go 模块中特别有用,因为它可以确保生成的代码与你的模块结构保持一致

 

编译结果:

Json 和 Protobuf 的对比


在当今的软件开发中,数据交换是必不可少的环节。Protobuf和JSON是两种广泛使用的数据交换格式,它们各自具有独特的优势和适用场景。下面将从多个方面对Protobuf和JSON进行对比分析。

1)性能

Protobuf是一种高效的二进制序列化格式,它在数据传输和存储方面的性能优于JSON。由于Protobuf采用二进制编码,因此在相同数据量的情况下,序列化和反序列化的速度更快,且数据体积更小。相比之下,JSON是一种文本格式,其编码较为冗长,且解析速度相对较慢。因此,在处理大量数据或对性能要求较高的场景下,Protobuf更具优势。

2)可读性

JSON的优点在于其易于阅读和编写。JSON数据的结构清晰,语法简单,使得开发人员能够轻松地读写和理解数据。而Protobuf的二进制编码方式则较为复杂,不易于直接阅读。因此,在需要易于阅读和调试的场景下,JSON更为合适。

3)可扩展性

Protobuf具有更好的可扩展性。它支持自定义消息类型和字段标签,允许用户根据需要定义复杂的数据结构。此外,Protobuf还支持多种编程语言的实现,使得在不同语言间进行数据交换更加方便。相比之下,JSON虽然也可以表示复杂的数据结构,但其扩展性相对较差,且不支持自定义标签等高级功能。因此,在需要定义复杂数据结构或跨语言数据交换的场景下,Protobuf更具优势。

4)安全

Protobuf和JSON在安全性方面各有千秋。Protobuf采用加密传输的方式保证数据的安全性,而JSON则可以通过适当的加密算法对数据进行加密处理。另外,由于Protobuf采用二进制编码,相对于JSON的文本格式更难以被直接查看和修改,从而提高了数据的安全性。然而,在实际应用中,为了确保数据的安全性,无论使用Protobuf还是JSON都需要采取相应的安全措施,如加密传输、校验数据完整性等。因此,在安全性方面没有绝对的优劣之分。

5)流行度与生态系统

JSON在互联网领域的应用非常广泛,已经成为RESTful API的标准数据格式之一。许多常用的编程语言和框架都支持JSON的处理和解析,这使得JSON在开发社区中拥有庞大的生态系统。而Protobuf虽然也得到了许多公司和项目的采用,但其流行度和生态系统相对较小。因此,在选择数据交换格式时,需要考虑项目需求和开发团队的技能背景。

综上所述,Protobuf和JSON各有千秋,需要根据实际需求选择合适的数据交换格式。在处理大量数据或对性能要求较高的场景下,Protobuf更具优势;而在需要易于阅读和调试的场景下,JSON更为合适。另外,如果项目需要定义复杂的数据结构或跨语言数据交换,应优先考虑使用Protobuf;如果项目主要应用于互联网领域,则JSON可能更适合。在选择数据交换格式时,还需要综合考虑安全性、流行度以及生态系统等方面的因素。

 

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

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

相关文章

提升效率!商务电子邮件在WorkPlace中如何高效运用?安全保障!

高效和安全的沟通是任何组织成功的核心。在我们关于电子邮件类型的系列文章的第二期中,我们将重点关注商业电子邮件在促进无缝交互中的关键作用。当你身处重要的工作场环境时,本系列的每篇文章都提供了电子邮件的不同维度的视角。 “2024年,全…

算法系列--递归

一.如何理解递归 递归对于初学者来说是一个非常抽象的概念,笔者在第一次学习时也是迷迷糊糊的(二叉树遍历),递归的代码看起来非常的简洁,优美,但是如何想出来递归的思路或者为什么能用递归这是初学者很难分析出来的 笔者在学习的过程中通过刷题,也总结出自己的一些经验,总结来…

C语言例3-39:赋值时类型转换可能出现错误的例子

进行数据类型转换时,需要注意以下几点: 强制类型转换获得的是一个所需类型的中间量,原来表达式的类型并不发生变化。例如(double)a只是将变量a的值转换成一个double型的中间量,但其数据类型并未转换为double型表达式计算过程中&a…

Java开发---上海得帆(一面)

面试感受 这是我的第一次面试,我感觉我这次面试的很差,很糟糕,十分的糟糕,万分的糟糕。第一次面试,面试了半个小时。我去真的好紧张,脑子里一篇空白。脑子空白还不是最惨的,最惨的是那个八股文…

游戏客户端开发

1、LOL里面用到的是什么同步机制? 2、网络不好的情况下人物会出现瞬移等情况,怎样避免? 3、游戏里面有没有涉及数据存储,如存档之类的?、 4、如果让你设计存档,会如何着手? 5、以二进制方式…

反光衣AI检测识别算法---豌豆云

工服反光衣穿戴AI检测识别算法是一项基于人工智能视觉智能分析的创新技术。 它通过使用现场摄像头对工地进行全天候、不间断的监测,旨在提高工地安全管理水平。 这个系统的核心功能是自动检测和识别潜在的危险行为,例如未穿戴工服、反光衣、安全带或未…

聊一聊基础

基础 1、面向对象编程是什么? 面向对象编程在解决问题的时候,会先抽象出对象,再使用对象去解决问题。 面向过程把解决问题的过程拆成一个个方法,通过一个个方法的执行解决问题。 面向对象编程有三大特性,继承、封装…

containerd管理命令ctr常用操作 —— 筑梦之路

Containerd ctr、crictl、nerdctl客户端命令——筑梦之路_crictl login-CSDN博客 镜像常用操作 1. 拉取镜像 ctr images pull docker.io/library/nginx:alpine 注意:containerd支持oci标准的镜像,所以可以直接使用docker官方或dockerfile构建的镜像 需…

RabbitMQ--04--Spring Cloud Stream(消息驱动)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1.Spring Cloud Stream1. 基本介绍https://spring.io/projects/spring-cloud-stream#overview 2.Spring Cloud Stream 解决的痛点问题3.设计思想Stream为什么可以统…

2024网络安全-自学笔记

前言 一、什么是网络安全 网络安全可以基于攻击和防御视角来分类,我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术,而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域,都有攻与防…

新火种AI|国产手机抢滩“AI+折叠屏”赛道,行业洗牌大战就此开启?

作者:小岩 编辑:彩云 从2023年到2024年,随着新一波人工智能浪潮的加速,消费电子产品也迎来了全新的话题——AI。更重要的是,这场战争看似没有硝烟,但各大厂商都已经暗自角力了许久,特别是手机…

Java二阶知识点总结(八)Linux和Docker

Linux 1、常用命令: cat:查看文件内容cd:切换目录ifconfig或ip addr:用于查看网络接口的地址和参数pwd:显示当前目录的绝对路径ls/ll:查看当前目录下的所有文件touch:创建文件mkdir&#xff1…

Windows 11 鼠标右键可选择 cmd 命令行选项

** Windows 11 鼠标右键可选择 cmd 命令行选项 ** 在文件夹内打开命令行,只能使用 Windows 自带的 PowerShell , 作为一个 cmd 重度使用用户来说很是折磨,需要打开 cmd 然后切换盘符再 cd 。。。 现在咱们自己创建一个可以打开 cmd 的方法…

Qt调用内置图标

int IconIndex0; QIcon icon QApplication::style()->standardIcon((QStyle::StandardPixmap)IconIndex);按以上代码可以调用Qt内置的71个图标,只要变换IconIndex就可以了,IconIndex为[0,70]。显示如下:图标index名称。

图论中的最小生成树:Kruskal与Prim算法深入解析

🎬慕斯主页:修仙—别有洞天 ♈️今日夜电波:アンビバレント—Uru 0:24━━━━━━️💟──────── 4:02 🔄 ◀️ ⏸ ▶️ ☰ …

游戏客户端-面经

做一道题:一副牌,能不能全凑成顺子和同花对C是什么级别的认知。内联函数可不可以是虚函数New和malloc有什么区别多态有几种静态多态是什么,动态多态是什么?什么是拷贝构造函数什么情况下要自己写拷贝构造函数什么是移动构造函数深…

Meta分析:如何为生态环境领域提供可靠结论

Meta分析,又称元分析,是一种统计方法,用于整合多个独立研究的结果,从而得出更为全面、可靠的结论。在生态领域,Meta分析发挥着越来越重要的作用,它有助于解决单个研究样本量小、结果不一致等问题&#xff0…

西井科技与安通控股签署战略合作协议 共创大物流全新生态

2024年3月21日,西井科技与安通控股在“上海硅巷”新象限空间正式签署战略合作框架协议。双方基于此前在集装箱物流的成功实践与资源优势,积极拓展在AI数字化产品、新能源自动驾驶解决方案和多场景应用,以及绿色物流链等领域的深度探索、强强联…

洛克王国卡小游戏2

kaijiang1.setBackground(Color.WHITE);/*去除按钮背景kaijiang1.setContentAreaFilled(false);*///添加到界面getContentPane().add(kaijiang1);}private void extracted1() {JLabel beijin new JLabel(new ImageIcon("D:\\bc2\\kaixinge\\wendang\\2266.png"));be…

视频号下载助手失效了?如何解决下载视频问题!

在刷短视频的时候难免会遇到部分的视频号视频下载不下来,那我们该如何解决视频号下载问题呢? 视频号下载助手解决方案 视频号下载助手失效分为两种情况! 1、可以解析,但不能下载 根据使用视频号下载助手常见的问题,我们发现会有…