最近写了一些 Java 的 gRPC, 涉及到 protobuf 和 maven 还有 gitlab CI 的问题, 整理一下.
0x00 proto 代码管理
使用 gRPC 就少不了 protobuf. proto 文件的管理和项目间共享问题, 推荐一个思路:
- 所有的 proto 文件放到一个项目里, 统一在一个 git 项目中管理
- 使用 gitlab ci 自动检查 proto 文件语法, 在 commit 的时候自动跑 ci
- 所有人使用 Merge Request 修改 proto 文件, code review
0x01 Java 项目中引用 proto 文件
Java 项目中使用 proto 文件, 建议使用 git submodule
功能, 将 protobuf 项目作为 submodule 添加到工程项目中, 仅仅 include
用到的几个文件.
maven 工程中配置如下:
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.4.1.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</version>
<configuration>
<protocArtifact>
com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}
</protocArtifact>
<!-- pluginId 和 pluginArtifact 只有在需要生成 gRPC 服务的时候使用, 如果不需要 gRPC 服务, 可以删除这两个元素 -->
<pluginId>grpc-java</pluginId>
<pluginArtifact>
io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
</pluginArtifact>
<!-- 这里是 protobuf 文件的路径 -->
<protoSourceRoot>${basedir}/{your_protobuf_dir}</protoSourceRoot>
<includes>
<!-- 这里写一些包含的文件相对路径 -->
<include>{some_files}</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
这样的好处有如下几点:
- 所有的代码都是 git 管理, 避免相互拷贝 proto 文件
- build 过程全部依赖 maven 实现, 无需额外脚本
- 平台无关, 通过
os-maven-plugin
插件屏蔽了 os, mac 上开发, *nix build 无障碍
0x02 gitlab ci 中 git submodule 问题
由于使用了 git submodule 功能, 导致在默认情况下 gitlab 的 ci runner 仅仅 clone 了主项目代码, 没有 submodule 的内容. 修复的办法也很简单:
- gitlab submodule 中使用相对路径, 参见 gitlab 官方文档
- 项目的
.gitlab-ci.yml
中添加如下变量, clone 的时候 recursive 下载 submodule 代码
variables:
GIT_SUBMODULE_STRATEGY: recursive
总结
看上去很简单的事情, 折腾了好几个小时. 写出来大家开心一下, 开箱机用.