protobuf 是做什么的
专业的解答:
Protocol Buffers 是一种轻便高效的结构化数据存储格式,可用于结构化数据串行化,很适合做数据存储或 RPC 数据交换格式。它可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。简单的说就是干和xml一样的事,把某种数据结构的信息,以某种格式保存起来。主要用于数据存储、传输协议格式等场合
了解了下这种数据格式使用的场景。
1、RPC序列化,转自:http://blog.leanote.com/post/weibo-007/f40e8fee0dfb
在PRC框架中,数据的传输发生在客户端和服务端,而我们知道基于TCP协议最终传输的是二进制的0/1序列。所以,基于TCP传输协议的RPC服务自然也需要将数据结构转换成二进制,和二进制转换成数据结构的功能。所以,原则上,基于网络的数据传输只能传输二进制表示的字符串
但是,传输的二进制序列是完全没有意义的,除非有一套解析二进制串的协议。没错,这个协议可以就是目前我们大家熟知的xml,json协议。当然。除了这两者,还有其他的的序列化和反序列化协议。
XMl
<note>
<to>George</to>
<from>John</from>
<msg>Don't forget the meeting!</msg>
</note>
可以看出这种序列化协议的优点是可读性和易调试行。但是这种协议的缺点也很明显:额外空间开销大,序列化之后的数据量剧增。
JSON
{
"to":"George",
"from":"John",
"msg":"Don't forget the meeting!"
}
这种序列化协议有很大的优势:
1. 这样表示非常符合工程师对对象的理解,尤其是js工程师
2. 和xml一样,可读性强
3. 和xml相比,更加节省空间,解析速度更快
4. 由于天生的Web友好型,JSON自然而然成了AJAX数据传输的标准协议。JSON目前的使用非常广泛,但是,如果数据传输和响应时间有跟苛刻的要求,那么JSON可能性能还是差点。
Protobuf (Google Protocol Buffer)数据结构定义文件的格式如下:
syntax = "proto3";
package config;
message MailConfig{
string to = 1;
string from = 2;
string msg = 3;
}
然后这个协议文件客户端和服务端都需要用到。这样,网络发送字节就不需要发送和数据无关的字节了。针对上面的数据结构,序列化成json的长度是63,而按照Protobuf协议序列化之后的长度是41。如果数据更多,效果更明显。
PHP如果要使用protobuf 需要安装 proto + 安装protobuf composer包
proto 用于根据protobuf数据结构文件(.proto)生成对应的类,用于生成protobuf文件
安装 google/protobuf composer 包composer require google/protobuf
proto下载地址
工具包 版本 下载地址
proto 3.0.0 https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-php-3.3.0.zip
使用案例:
我们首先新建一个文件夹app。然后在app文件夹内新建composer.json文件,文件内容如下:
{
"require":{
"google/protobuf": "^3.3"
}
}
保存之后,在app文件夹下执行composer install安装命令
书写 .proto 文件
我们知道,二进制序列如果没有协议,根本不知道它表示的是什么,首先我们需要编写一个 proto 文件,定义我们程序中需要处理的结构化数据,在 protobuf的术语中,结构化数据被称为 Message。我们这里定义一个mail的proto文件mail.proto,这个文件还是放在我们的app目录下, 文件内容如下:
其中,syntax表示我们使用的是proto3语法规则。packge的名字叫做mail,然后定义了一个名字为MailConfig的消息。这个消息有3个成员,string类型的to,string类型的from,string类型的msg。
syntax = "proto3";
package mail;
message MailConfig{
string to = 1;
string from = 2;
string msg = 3;
}
编译 .proto 文件,这里我们需要使用protoc,将.proto文件生成目标PHP语言。–php-out表示生成目标语言存放位置,我们就放在当前目录下,也就是app文件夹下
protoc --php_out=. mail.proto
编写测试
<?php
require_once('vendor/autoload.php');
require_once('GPBMetadata/Mail.php');
require_once('Mail/MailConfig.php');
/**
* Writer写数据,Protobuf抽象成调用相关set函数即可
*/
$foo = new \Mail\MailConfig();
$foo->setTo("George");
$foo->setFrom("John");
$foo->setMsg("Don't forget the meeting!");
$packed = $foo->serializeToString();//这里你也可以选择serializeToJsonString序列化成JSON
//Reader读数据,Protobuf抽象成调用相关get函数即可
$res = new \Mail\MailConfig();
$res->mergeFromString($packed);
$jsonArr = [
"to"=> $res->getTo(),
"from"=> $res->getFrom(),
"msg"=> $res->getMsg(),
];
var_dump($jsonArr);
输出:
array(3) {
["to"]=>
string(6) "George"
["from"]=>
string(4) "John"
["msg"]=>
string(25) "Don't forget the meeting!"
}
这就是一个典型的序列化和反序列化的例子,试想一下,如果我们将序列化好的二进制串通过网络发送到另一端,而另一端再使用同样的.proto文件生成的目标语言解析。这将变得比json更加的高效。因为我们可以传输更少的字节,反序列化速度也非常快。
如果使用composer包效率比较低,可以使用protobuf 的PHP C扩展,安装方法如下:
git clone https://github.com/allegro/php-protobuf
cd php-protobuf/
phpize
./configure
make && make install
//然后在php.ini里面加一下extension = "protobuf.so",再重启php-fpm
protoc --php_out=./ jrttDmp.proto
附录:
一看就懂系列之 protobuf的php版的教程https://blog.csdn.net/u011957758/article/details/52455231
PHP protobuf 扩展 https://github.com/allegro/php-protobuf
Google protobuf 所有语言扩展 https://github.com/protocolbuffers/protobuf
protobuf3 使用 https://www.jianshu.com/p/d2bdc966086b
————————————————
版权声明:本文为CSDN博主「o王o」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u012129607/article/details/95758405
没有帐号? 现在注册.