gRPC服务定义:将.proto编译容器化?

huangapple go评论71阅读模式
英文:

gRPC service definitions: containerize .proto compilation?

问题

让我们假设我们有一个包含 gRPC 服务定义的 services.proto 文件,例如:

service Foo {
  rpc Bar (BarRequest) returns (BarReply) {}
}

message BarRequest {
  string test = 1;
}

message BarReply {
  string test = 1;
}

我们可以通过以下命令将其编译为 Go 代码:

$ protoc --go_out=. --go_opt=paths=source_relative \
    --go-grpc_out=. --go-grpc_opt=paths=source_relative \
    services.proto

然而,我担心运行最后一步可能会产生不一致的输出,这取决于安装的 protobuf 编译器版本和 gRPC 的 Go 插件。例如,两个在同一项目上工作的开发人员可能在本地安装了稍微不同的版本。

我认为通过将 protoc 步骤容器化来解决这个问题是合理的。例如,可以使用以下 Dockerfile

FROM golang:1.18
WORKDIR /src
RUN apt-get update && apt-get install -y protobuf-compiler
RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26
RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1
CMD protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative services.proto

然后,在容器中运行 protoc 步骤:

docker run --rm -v $(pwd):/src $(docker build -q .)

将上述命令封装在一个 shell 脚本中后,开发人员可以在本地机器上运行它,从而获得确定性和可重现的输出。它也可以在 CI/CD 流水线中运行。

我的问题是,这种方法是否可行,或者是否有更简单的方法来实现相同的结果?

值得注意的是,我惊讶地发现官方的 grpc/go 镜像没有预安装 protoc。我是否偏离了常规做法?

英文:

Let's say we have a services.proto with our gRPC service definitions, for example:

service Foo {
  rpc Bar (BarRequest) returns (BarReply) {}
}

message BarRequest {
  string test = 1;
}

message BarReply {
  string test = 1;
}

We could compile this locally to Go by running something like

$ protoc --go_out=. --go_opt=paths=source_relative \
    --go-grpc_out=. --go-grpc_opt=paths=source_relative \
    services.proto

My concern though is that running this last step might produce inconsistent output depending on the installed version of the protobuf compiler and the Go plugins for gRPC. For example, two developers working on the same project might have slightly different versions installed locally.

It would seem reasonable to me to address this by containerizing the protoc step. For example, with a Dockerfile like this...

FROM golang:1.18
WORKDIR /src
RUN apt-get update && apt-get install -y protobuf-compiler
RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26
RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1
CMD protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative services.proto

... we can run the protoc step inside a container:

docker run --rm  -v $(pwd):/src $(docker build -q .)

After wrapping the previous command in a shell script, developers can run it on their local machine, giving them deterministic, reproducible output. It can also run in a CI/CD pipeline.

My question is, is this a sound approach and/or is there an easier way to achieve the same outcome?

NB, I was surprised to find that the official grpc/go image does not come with protoc preinstalled. Am I off the beaten path here?

答案1

得分: 1

我的问题是,这是一个可行的方法吗?还是有更简单的方法可以实现相同的结果?

这绝对是一个好方法。我也是这样做的。不仅可以在团队中保持一致,还可以确保我们可以在不同的操作系统上产生相同的输出。

不过,还有一种更简单的方法可以实现相同的结果。你可以查看这个仓库:https://github.com/jaegertracing/docker-protobuf

这个镜像在Docker Hub上,但如果你愿意,你也可以创建自己的镜像。

我使用以下命令来生成Go代码:

docker run --rm -u $(id -u)  \
    -v${PWD}/protos/:/source  \
    -v${PWD}/v1:/output  \
    -w/source jaegertracing/protobuf:0.3.1  \
      --proto_path=/source \
      --go_out=paths=source_relative,plugins=grpc:/output \
      -I/usr/include/google/protobuf  \
      /source/* 
英文:

> My question is, is this a sound approach and/or is there an easier way to achieve the same outcome?

It is definitely a good approach. I do the same. Not only to have a consistent across the team, but also to ensure we can produce the same output in different OSs.

There is an easier way to do that, though.
Look at this repo: https://github.com/jaegertracing/docker-protobuf

The image is in Docker hub, but you can create your image if you prefer.

I use this command to generate Go:

docker run --rm -u $(id -u)  \
    -v${PWD}/protos/:/source  \
    -v${PWD}/v1:/output  \
    -w/source jaegertracing/protobuf:0.3.1  \
      --proto_path=/source \
      --go_out=paths=source_relative,plugins=grpc:/output \
      -I/usr/include/google/protobuf  \
      /source/* 

huangapple
  • 本文由 发表于 2022年4月5日 02:59:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/71742438.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定