【工程实践】如何对 GRPC Protobuf 文件进行管理?

问题描述

因为工作的需求,这个月花了较多的时间投入到 GRPC 框架的学习和使用上。包括 GRPC 项目结构的搭建,跨 GRPC 服务中 context 的传递,GRPC interceptor 的使用,接口测试, 以及关于 protobuf 文件的管理。因为之前有 RPC 框架使用经验,所以上手还算是比较快的。

但是关于 GRPC IDL 文件的管理还是花了不少心思去研究了一下。之前在腾讯的时候,有一个独立的平台来对 protobuf 文件进行管理,可以直接在平台上进行 protobuf 文件的定义和修改,并且平台会帮你生成桩代码,且提供版本管理的功能。因为目前所在公司并没有提供这个的平台,所以 protobuf 文件的管理需要另寻它法。

解决方案

经过调研,大体上有三种方法。

第一种:存放在代码仓库,直接将项目所依赖到的所有 Proto 文件都存放在 proto/ 目录下,不经过开发工具的自动拉取和发布。但是这种一份 proto 文件需要多处维护,容易造成不一致。并且每次都需要程序员手动去介入 复制粘贴。基本都是不采纳的。只建议自己学习练习的时候可以这样使用。

第二种:独立仓库,即用一个独立的仓库来管理所有的 protobuf 文件。提前提供好生成桩代码的脚本文件,将生成的桩代码作为 sdk 引入使用。

第三种:镜像仓库,也是用一个独立的仓库来管理所有的 protobuf 文件。通过 ci 生成桩代码,并将桩代码同步到镜像仓库中(可以是一个 api 大仓,或者是多个子项目的小仓)。主要目的是将 protobuf 文件和桩代码文件分开管理。

同时对于第二种和第三种方法,在使用上,也有不同选择。用户可以选择用 submodule 的方法,也可以使用 se mantic version。

基于一些对比思考,我最终采用了镜像仓库 + api 大仓(通过结构来划分领域) + semantic version.

其中 repo flow 如下:

protobuf management gitaction work flow

版本号管理如下:

1
2
tag template: v{MAJOR}.{MINOR}.{PATCH}
for example: v1.0.11

reference: Semantic Versioning 2.0.0

理由如下:镜像仓库将 protobuf 文件和桩代码分开管理,满足接口定义与实现划分的抽象理念,后续如果有其他语言的服务,方便扩展(修改 ci 即可)。根据 googleapis 的设计,以及我们服务的规模(体量小,微服务划分不算太多),我们倾向于对于 protobuf 的统一管理,即 api 大仓。同时采用 semantic version 来进行版本管理, 没有选择 submodule 的方式主要是因为 semantic version 这种方式更容易理解和使用,submodule 更多是用在 go 语言项目中,并且基于分支的使用方式不利于后续的管理,且在出现错误的时候,需要回滚代码。

Reference