Files
go-zero/tools/goctl/rpc/README-cn.md

9.9 KiB
Raw Permalink Blame History

goctl rpc — RPC 代码生成

English | 中文

goctl rpc 是 goctl 脚手架下的 RPC 服务代码生成模块,基于 .proto 文件生成完整的 zRPC 服务代码。你只需编写 proto 定义和业务逻辑,其余代码均由工具自动生成。

特性

  • 贴近 protoc:与 protoc 完全兼容,透传所有 protoc 参数
  • 外部 Proto 导入:支持跨目录、跨包的 proto 导入,自动解析传递性依赖
  • 多服务模式:单个 proto 文件中定义多个 service按服务名自动分组
  • 流式支持:支持服务端流、客户端流和双向流
  • Google 标准类型:自动识别 google.protobuf.* 类型并生成正确的 Go 导入
  • 客户端生成:自动生成封装好的 RPC 客户端代码

前置条件

# 安装 protoc 插件
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

快速开始

方式一:一键创建服务

goctl rpc new greeter

生成完整的项目结构:

greeter/
├── etc/
│   └── greeter.yaml
├── greeter/
│   ├── greeter.pb.go
│   └── greeter_grpc.pb.go
├── greeter.go
├── greeter.proto
├── greeterclient/
│   └── greeter.go
└── internal/
    ├── config/
    │   └── config.go
    ├── logic/
    │   └── pinglogic.go
    ├── server/
    │   └── greeterserver.go
    └── svc/
        └── servicecontext.go

方式二:基于 Proto 文件生成

  1. 生成 proto 模板:
goctl rpc template -o=user.proto
  1. 初始化输出目录并生成服务代码:
mkdir -p output && cd output && go mod init example.com/demo && cd ..
goctl rpc protoc user.proto \
  --go_out=output --go-grpc_out=output --zrpc_out=output \
  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \
  --module=example.com/demo -I .

命令参考

goctl rpc protoc

.proto 文件生成 zRPC 服务代码。

goctl rpc protoc <proto_file> [flags]

示例:

# 基础用法
goctl rpc protoc user.proto \
  --go_out=output --go-grpc_out=output --zrpc_out=output \
  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \
  --module=example.com/demo -I .

# 多服务模式
goctl rpc protoc multi.proto \
  --go_out=output --go-grpc_out=output --zrpc_out=output \
  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \
  --module=example.com/demo -I . -m

# 导入外部 proto
goctl rpc protoc service.proto \
  --go_out=output --go-grpc_out=output --zrpc_out=output \
  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \
  --module=example.com/demo -I . -I ./shared_protos

# 使用 Google 标准类型
goctl rpc protoc service.proto \
  --go_out=output --go-grpc_out=output --zrpc_out=output \
  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \
  --module=example.com/demo -I .

参数说明:

参数 缩写 类型 默认值 说明
--zrpc_out string 必填 zRPC 服务代码输出目录
--go_out string 必填 protoc Go 代码输出目录
--go-grpc_out string 必填 protoc gRPC 代码输出目录
--go_opt string protoc-gen-go 选项(如 module=example.com/demo
--go-grpc_opt string protoc-gen-go-grpc 选项(如 module=example.com/demo
--proto_path -I string[] proto 导入搜索目录(可多次指定)
--multiple -m bool false 多服务模式
--client -c bool true 是否生成 RPC 客户端代码
--style string gozero 文件命名风格
--module string 自定义 Go module 名称
--name-from-filename bool false 使用文件名而非 package 名命名服务
--verbose -v bool false 显示详细日志
--home string goctl 模板目录
--remote string 远程模板 Git 仓库地址
--branch string 远程模板分支

goctl rpc new

快速创建一个完整的 RPC 服务项目。

goctl rpc new <service_name> [flags]

参数说明:

参数 缩写 类型 默认值 说明
--style string gozero 文件命名风格
--client -c bool true 是否生成 RPC 客户端代码
--module string 自定义 Go module 名称
--verbose -v bool false 显示详细日志
--idea bool false 生成 IDE 项目标记
--name-from-filename bool false 使用文件名而非 package 名命名服务
--home string goctl 模板目录
--remote string 远程模板 Git 仓库地址
--branch string 远程模板分支

goctl rpc template

生成 proto 文件模板。

goctl rpc template -o=<output_file> [flags]

参数说明:

参数 类型 说明
-o string 输出文件路径(必填)
--home string goctl 模板目录
--remote string 远程模板 Git 仓库地址
--branch string 远程模板分支

功能详解

多服务模式(--multiple

当 proto 文件包含多个 service 定义时,必须使用 --multiple 标志。

service SearchService {
  rpc Search(SearchReq) returns (SearchReply);
}

service NotifyService {
  rpc Notify(NotifyReq) returns (NotifyReply);
}

启用 --multiple 后的目录变化:

特性 默认模式 --multiple 模式
服务数量 仅 1 个 1 个或多个
客户端目录 以服务名命名 固定为 client/
代码组织 扁平结构 按服务名分组

--multiple=false(默认)的目录结构:

output/
├── greeterclient/
│   └── greeter.go
├── internal/
│   ├── logic/
│   │   └── sayhellologic.go
│   └── server/
│       └── greeterserver.go
└── ...

--multiple=true 的目录结构:

output/
├── client/
│   ├── searchservice/
│   │   └── searchservice.go
│   └── notifyservice/
│       └── notifyservice.go
├── internal/
│   ├── logic/
│   │   ├── searchservice/
│   │   │   └── searchlogic.go
│   │   └── notifyservice/
│   │       └── notifylogic.go
│   └── server/
│       ├── searchservice/
│       │   └── searchserviceserver.go
│       └── notifyservice/
│           └── notifyserviceserver.go
└── ...

外部 Proto 导入(--proto_path

通过 -I / --proto_path 指定额外的 proto 搜索目录,支持以下场景:

  • 同目录导入import "types.proto";
  • 子目录导入import "common/types.proto";
  • 外部目录导入proto 文件位于项目外部
  • 传递性导入A 导入 BB 导入 Cgoctl 自动递归解析
  • 跨包导入:不同 go_package 的 proto 文件,自动生成正确的 Go 导入
# 从多个目录搜索 proto 文件
goctl rpc protoc service.proto \
  --go_out=output --go-grpc_out=output --zrpc_out=output \
  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \
  --module=example.com/demo \
  -I . -I ./shared_protos -I /path/to/external_protos

服务命名

默认情况下,服务名称来自 proto 的 package 名称(例如 package user; → 服务名 user)。这使得多个 proto 文件可以共享同一个 package

protos/
├── user_base.proto      # package user;
├── user_auth.proto      # package user;
└── user_profile.proto   # package user;

三个文件会生成到同一个 user 服务中。

如需使用 proto 文件名命名(旧版行为),请添加 --name-from-filename 标志。

流式 RPC

支持 gRPC 的三种流式模式:

service StreamService {
  rpc ServerStream(Req) returns (stream Reply);       // 服务端流
  rpc ClientStream(stream Req) returns (Reply);       // 客户端流
  rpc BidiStream(stream Req) returns (stream Reply);  // 双向流
}

Google 标准类型

goctl 自动识别并正确处理 Google protobuf 标准类型:

Proto 类型 Go 类型
google.protobuf.Empty emptypb.Empty
google.protobuf.Timestamp timestamppb.Timestamp
google.protobuf.Duration durationpb.Duration
google.protobuf.Any anypb.Any
google.protobuf.Struct structpb.Struct
google.protobuf.FieldMask fieldmaskpb.FieldMask
google.protobuf.*Value wrapperspb.*Value

这些类型可直接用作 RPC 参数类型goctl 会自动生成正确的导入。


完整示例

详见 example/ 目录,包含 10 个完整示例,覆盖所有生成场景。

# 示例 场景
01 基础服务 单服务,无导入
02 同级导入 导入同目录 proto
03 子目录导入 导入子目录 proto
04 传递性导入 A → B → C 依赖链
05 多服务 --multiple 模式
06 标准类型 消息中使用 Timestamp 等
07 外部 Proto同包 外部 proto相同 go_package
08 外部 Proto跨包 外部 proto不同 go_package
09 标准类型作参数 Empty/Timestamp 作为 RPC 参数
10 流式通信 服务端/客户端/双向流