最近寫了一些 Java 的 gRPC, 涉及到 protobuf 和 maven 還有 gitlab CI 的問題, 整理一下.
0x00 proto 代碼管理
使用 gRPC 就少不了 protobuf. proto 文件的管理和項(xiàng)目間共享問題, 推薦一個思路:
- 所有的 proto 文件放到一個項(xiàng)目里, 統(tǒng)一在一個 git 項(xiàng)目中管理
- 使用 gitlab ci 自動檢查 proto 文件語法, 在 commit 的時候自動跑 ci
- 所有人使用 Merge Request 修改 proto 文件, code review
0x01 Java 項(xiàng)目中引用 proto 文件
Java 項(xiàng)目中使用 proto 文件, 建議使用 git submodule 功能, 將 protobuf 項(xiàng)目作為 submodule 添加到工程項(xiàng)目中, 僅僅 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 服務(wù)的時候使用, 如果不需要 gRPC 服務(wù), 可以刪除這兩個元素 -->
<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>
這樣的好處有如下幾點(diǎn):
- 所有的代碼都是 git 管理, 避免相互拷貝 proto 文件
- build 過程全部依賴 maven 實(shí)現(xiàn), 無需額外腳本
- 平臺無關(guān), 通過
os-maven-plugin插件屏蔽了 os, mac 上開發(fā), *nix build 無障礙
0x02 gitlab ci 中 git submodule 問題
由于使用了 git submodule 功能, 導(dǎo)致在默認(rèn)情況下 gitlab 的 ci runner 僅僅 clone 了主項(xiàng)目代碼, 沒有 submodule 的內(nèi)容. 修復(fù)的辦法也很簡單:
- gitlab submodule 中使用相對路徑, 參見 gitlab 官方文檔
- 項(xiàng)目的
.gitlab-ci.yml中添加如下變量, clone 的時候 recursive 下載 submodule 代碼
variables:
GIT_SUBMODULE_STRATEGY: recursive
總結(jié)
看上去很簡單的事情, 折騰了好幾個小時. 寫出來大家開心一下, 開箱機(jī)用.