Golang中如何在不同仓库间共享.proto文件
Golang中如何在不同仓库间共享.proto文件
假设有两个服务位于不同的代码仓库中(客户端和服务器端)。它们通过 gRPC 进行通信,因此需要编译 .proto 文件以生成相应的存根。
问题是如何在这些服务之间共享这些文件?
我想为 proto 模式创建第三个仓库。我了解到的方法是:将更改推送到该仓库,然后通过 CI/CD 自动生成存根,将其打包(使用 Maven?)并上传到某种注册中心(例如 GitHub Packages)。接着,将其作为包下载(在 Java 中使用 pom.xml),并包含在项目中。
在这样的配置过程中,我遇到了一些问题。 你能给我一些建议、想法或不同的方法吗?
更多关于Golang中如何在不同仓库间共享.proto文件的实战教程也可以访问 https://www.itying.com/category-94-b0.html
另一种解决方案是将 proto-schemas 仓库作为 Git 子模块添加到两个服务的仓库中。你必须在两个构建中都生成存根,但这消除了上传它们到注册中心的需求。
更多关于Golang中如何在不同仓库间共享.proto文件的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在阅读不同的选项时,我觉得子模块是一个可行的选择,但并非最佳,也不够灵活——无论如何,我会研究一下,谢谢。
让我再问第二个问题。我想在Kubernetes中开发一个应用,使用像Skaffold或Tilt-dev(<-- 更倾向于后者)这样的工具。这些工具有助于将服务自动部署到本地集群中,但如何托管数据库呢?我有docker-compose文件也可以运行它们,但在本地开发期间,我应该将它们放在集群外部还是内部?是否有可能在集群重启期间保持状态和数据?
谢谢。
在Go中跨仓库共享.proto文件的常见做法是使用独立的proto仓库配合Go Modules。以下是具体实现方案:
方案一:独立的proto仓库 + Go Modules
1. 创建独立的proto仓库
// 仓库:github.com/yourorg/protos
// user.proto
syntax = "proto3";
package yourorg.common.v1;
option go_package = "github.com/yourorg/protos/gen/go/yourorg/common/v1";
message User {
string id = 1;
string name = 2;
string email = 3;
}
2. 配置go.mod
// 在proto仓库中
module github.com/yourorg/protos
go 1.21
require google.golang.org/protobuf v1.32.0
3. 添加Makefile生成代码
# Makefile in proto repository
PROTO_DIR=.
GO_OUT_DIR=gen/go
.PHONY: gen
gen:
mkdir -p $(GO_OUT_DIR)
protoc --proto_path=$(PROTO_DIR) \
--go_out=$(GO_OUT_DIR) \
--go_opt=paths=source_relative \
$(PROTO_DIR)/**/*.proto
4. 在服务中引用
// 客户端服务go.mod
module github.com/yourorg/client
go 1.21
require github.com/yourorg/protos v1.0.0
replace github.com/yourorg/protos => ../protos // 本地开发时使用
// 客户端代码示例
package main
import (
"context"
"log"
pb "github.com/yourorg/protos/gen/go/yourorg/common/v1"
"google.golang.org/grpc"
)
func main() {
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
log.Fatal(err)
}
defer conn.Close()
client := pb.NewUserServiceClient(conn)
// 使用生成的客户端代码
}
方案二:使用buf工具链
1. 安装和配置buf
# buf.yaml (在proto仓库根目录)
version: v1
lint:
use:
- STANDARD
breaking:
use:
- FILE
2. 配置buf.gen.yaml
# buf.gen.yaml
version: v1
plugins:
- name: go
out: gen/go
opt: paths=source_relative
- name: go-grpc
out: gen/go
opt: paths=source_relative
3. 使用buf push到BSR
# 推送proto到Buf Schema Registry
buf push https://buf.build/yourorg/protos
4. 在其他服务中引用
// 通过go.mod引用BSR生成的代码
require buf.build/gen/go/yourorg/protos/protocolbuffers/go v1.32.0
方案三:Git Submodule方式
1. 添加submodule
# 在服务仓库中添加proto仓库作为submodule
git submodule add https://github.com/yourorg/protos protos
git submodule update --init --recursive
2. 本地生成代码脚本
// generate.go
package main
import (
"os"
"os/exec"
"path/filepath"
)
func main() {
protoDir := "./protos"
outputDir := "./gen"
cmd := exec.Command("protoc",
"--proto_path="+protoDir,
"--go_out="+outputDir,
"--go_opt=paths=source_relative",
"--go-grpc_out="+outputDir,
"--go-grpc_opt=paths=source_relative",
filepath.Join(protoDir, "**/*.proto"),
)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
}
方案四:容器化构建
1. Dockerfile for proto generation
FROM golang:1.21-alpine AS builder
RUN apk add --no-cache protobuf protobuf-dev
RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
WORKDIR /src
COPY . .
RUN mkdir -p gen && \
protoc --proto_path=. \
--go_out=gen \
--go_opt=paths=source_relative \
--go-grpc_out=gen \
--go-grpc_opt=paths=source_relative \
**/*.proto
2. CI/CD Pipeline示例
# .github/workflows/proto-release.yaml
name: Proto Release
on:
push:
tags:
- 'v*'
jobs:
generate-and-push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Generate Go code
uses: bufbuild/buf-setup-action@v1
with:
version: latest
- name: Generate
run: buf generate
- name: Push to registry
run: |
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git add gen/
git commit -m "Generated code for ${GITHUB_REF}"
git push
版本管理建议
使用语义化版本控制proto变更:
// go.mod中使用版本约束
require github.com/yourorg/protos v1.2.0
// 或者使用commit hash
require github.com/yourorg/protos v0.0.0-20240101120000-abcdef123456
这些方案中,方案一(独立仓库+Go Modules)在Go生态中最常用,方案二(buf工具链)提供了更完整的proto管理能力。选择哪种方案取决于团队规模和项目复杂度。

