浅析protobuf

92 阅读2分钟

是什么?

protobuf是Google公司提出的一种轻便高效的结构化数据存储格式,常用于

结构化数据的序列化,具有语言无关、平台无关、可扩展性特性,常用于通讯协议、服务端数据交换场景,

怎么实现

protobuf的核心内容包括:

  • 定义消息:消息的结构体,以message标识。
  • 定义接口:接口路径和参数,以service标识。

通过protobuf提供的机制,服务端与服务端之间只需要关注接口方法名(service)和参数(message)即可通信,而不需关注繁琐的链路协议和字段解析,极大降低了服务端的设计开发成本。

怎么使用

  • step1: 定义服务名SSR和方法名register
service SSR { rpc register(RegisterRequest) returns (RegisterResponse); };
  • step2: 定义接口参数和约束
message RegisterRequest {
    required string name = 1; // 姓名
    required string tel = 2; // 手机号 
    optional string email = 3; // 邮箱:可选 
}; 

message RegisterResponse {
    required int code = 1; // 错误码
    optional string err_msg = 2; // 错误信息 
};
  • step3: 使用protoc生成语言相关的协议代码
protoc -I . -I /usr/local/include -I $(GOPATH)/src --go_out=. ssr.proto

案列

/*头部相关声明*/
syntax = "proto3"; // 语法版本为protobuf3.0 
package user; // 定义包名,可以为.proto文件指定包名,防止消息名冲突。 
import "common.proto"; // 导入common.protooption 
 

//服务 
service User {rpc SayHello (SayHelloRequest) returns (SayHelloResponse) {}} 
//定义请求消息体 
message SayHelloRequest {string name = 1;int64 role = 2;} 
//定义响应消息体 
message SayHelloResponse {string message = 1;}

 ## protobuf坑和小技巧

  1. 字符串如果包含非英文字符,建议使用bytes字段
  2. 已有字段的field number不要修改
  3. 慎用required字段,容易造成不兼容的隐患(既不能删,又不能加)

命令生成:

protoc --proto_path=IMPORT_PATH
       --php_out=DST_DIR 
       --go_out=DST_DIR 
       path/to/file.proto
  • IMPORT_PATH声明了一个.proto文件所在的解析import具体目录。如果忽略该值,则使用当前目录。如果有多个目录则可以多次调用--proto_path,它们将会顺序的被访问并执行导入。
  • -I=IMPORT_PATH是--proto_path的简化形式。
  • --php_out在目标目录DST_DIR中产生php代码,可以在PHP代码生成参考中查看更多。
  • path/to/file.proto :你必须提议一个或多个.proto文件作为输入,多个.proto文件可以只指定一次。虽然文件路径是相对于当前目录的,每个文件必须位于其IMPORT_PATH下,以便每个文件可以确定其规范的名称。

参考资料