微服务 protobuf 文件管理方式

1,393 阅读2分钟

问题背景:

最近一直在使用 go-zero 微服务框架,其中让人最头疼的问题便是如何管理proto文件,因为他不能导入其他路径的包,就导致出现了很多次重复命名、不断地结构体转换等问题。


参考解决方法:

我将相同的结构体封装成了一个单独的module模块,然后上传到github再在proto文件中导入他。

参考文章:golang proto import 到底怎么做? 为什么? - 掘金 (juejin.cn)

这会导致自己的数据结构公开到github,如果你非常忌讳这种事情,或许可以试试本文推荐的方式


解决方法:

与上述方法相同,但是不将文件上传到github,而是将 option go_package 改成自己的项目目录。

我的demo目录如下:

image.png

其中app是存放项目主要逻辑(api、rpc)的目录,而model,则是存放相同protobuf结构体的目录,其中你可以以不同模块的名称来区分,我将订单表的相同结构体放到了model/order_vars/目录下


这是 order_vars.proto 文件内容:

syntax = "proto3";

option go_package = "protoDemo/model/order_vars";
package order_vars;

message goods {
  string goodsId = 1; // 商品ID
  string title = 2; // 商品名称
  string details = 3;
  float price = 4; // 单价
  repeated string pictures = 5; // 商品轮播图
  bytes parameter = 6;
}


message order {
  uint64 Id = 1;
  string Sn = 2;                 // 订单号
  uint64 UserId = 3;       // 客户信息
  uint64 StaffId = 4;     // 师傅信息
  string Address = 5;            // 地址
  string Tel = 6;                // 客户手机号
  string Remark = 7;             // 客户备注
  int64 ReservationTime = 8;     // 预约时间
  int64 CreateTime = 9;          // 创建时间
  int64 StartTime = 10;          // 开始时间
  int64 EndTime = 11;            // 结束时间
  int64 OrderType = 12;          // 类型
  int64 Status = 13;             // 状态
  float Earning = 14;            // 费用
}

我们现在生成他的Go文件,输出到model/order_vars/目录下!

protoc order_vars.proto --go_out=paths=source_relative:order_vars --go-grpc_out=paths=source_relative:order_vars

输出后的目录如下:

image.png

order.proto 的内容如下:

syntax = "proto3";

option go_package = "./pb";
package order;
import "order_vars.proto";

message NewOrderReq {
  order_vars.goods goods = 1;
}

message NewOrderResp {
  order_vars.order order = 1;
}

service orders {
  rpc NewOrder(NewOrderReq) returns (NewOrderResp);
}

现在生成他的rpc服务

$ goctl rpc protoc order.proto --go_out=../app/order/rpc --go-grpc_out=../app/order/rpc  --zrpc_out=../app/order/rpc --style=go_zero
Done.

image.png


要点

  • option go_package 表示被导入之后的import名称,可以灵活使用该参数,如果没有被导入,可以不指定。
  • 公共结构体使用 protoc 直接生成。
  • 建议将proto文件统一放到一个目录中(方便彼此调用,不过这可能会遇到其他问题,自己研究下吧)。

最后

在上述图片中,rpc服务已经生成了,另外他的公共结构体也没有报错,说明可以正常使用。

如果有什么其他问题,欢迎在评论区留言。

我用的目录结构并不是企业级别的哈,可以根据自己的业务或者规范去改,全文中最重要的便是 option go_package 表示被导入之后的import名称