|
@@ -8,74 +8,118 @@ Goctl Rpc是`goctl`脚手架下的一个rpc服务代码生成模块,支持prot
|
|
|
|
|
|
# 快速开始
|
|
# 快速开始
|
|
|
|
|
|
-### 生成proto模板
|
|
|
|
|
|
+### 方式一:快速生成greet服务
|
|
|
|
|
|
-```shell script
|
|
|
|
-$ goctl rpc template -o=user.proto
|
|
|
|
-```
|
|
|
|
|
|
+ 通过命令 `goctl rpc new ${servieName}`生成
|
|
|
|
|
|
-```golang
|
|
|
|
-syntax = "proto3";
|
|
|
|
-
|
|
|
|
-package remote;
|
|
|
|
-
|
|
|
|
-message Request {
|
|
|
|
- // 用户名
|
|
|
|
- string username = 1;
|
|
|
|
- // 用户密码
|
|
|
|
- string password = 2;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-message Response {
|
|
|
|
- // 用户名称
|
|
|
|
- string name = 1;
|
|
|
|
- // 用户性别
|
|
|
|
- string gender = 2;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-service User {
|
|
|
|
- // 登录
|
|
|
|
- rpc Login(Request)returns(Response);
|
|
|
|
-}
|
|
|
|
-```
|
|
|
|
-### 生成rpc服务代码
|
|
|
|
|
|
+ 如生成greet rpc服务:
|
|
|
|
|
|
-生成user rpc服务
|
|
|
|
-```
|
|
|
|
-$ goctl rpc proto -src=user.proto
|
|
|
|
-```
|
|
|
|
|
|
+ ```shell script
|
|
|
|
+ $ goctl rpc new greet
|
|
|
|
+ ```
|
|
|
|
|
|
-代码tree
|
|
|
|
|
|
+ 执行后代码结构如下:
|
|
|
|
|
|
-```
|
|
|
|
-user
|
|
|
|
|
|
+ ```golang
|
|
|
|
+ └── greet
|
|
├── etc
|
|
├── etc
|
|
- │ └── user.json
|
|
|
|
|
|
+ │ └── greet.yaml
|
|
|
|
+ ├── go.mod
|
|
|
|
+ ├── go.sum
|
|
|
|
+ ├── greet
|
|
|
|
+ │ ├── greet.go
|
|
|
|
+ │ ├── greet_mock.go
|
|
|
|
+ │ └── types.go
|
|
|
|
+ ├── greet.go
|
|
|
|
+ ├── greet.proto
|
|
├── internal
|
|
├── internal
|
|
│ ├── config
|
|
│ ├── config
|
|
│ │ └── config.go
|
|
│ │ └── config.go
|
|
- │ ├── handler
|
|
|
|
- │ │ ├── loginhandler.go
|
|
|
|
│ ├── logic
|
|
│ ├── logic
|
|
- │ │ └── loginlogic.go
|
|
|
|
|
|
+ │ │ └── pinglogic.go
|
|
|
|
+ │ ├── server
|
|
|
|
+ │ │ └── greetserver.go
|
|
│ └── svc
|
|
│ └── svc
|
|
│ └── servicecontext.go
|
|
│ └── servicecontext.go
|
|
- ├── pb
|
|
|
|
- │ └── user.pb.go
|
|
|
|
- ├── shared
|
|
|
|
- │ ├── mockusermodel.go
|
|
|
|
- │ ├── types.go
|
|
|
|
- │ └── usermodel.go
|
|
|
|
- ├── user.go
|
|
|
|
- └── user.proto
|
|
|
|
-
|
|
|
|
-```
|
|
|
|
|
|
+ └── pb
|
|
|
|
+ └── greet.pb.go
|
|
|
|
+ ```
|
|
|
|
+
|
|
|
|
+rpc一键生成常见问题解决见 <a href="#常见问题解决">常见问题解决</a>
|
|
|
|
+### 方式二:通过指定proto生成rpc服务
|
|
|
|
+
|
|
|
|
+* 生成proto模板
|
|
|
|
+
|
|
|
|
+ ```shell script
|
|
|
|
+ $ goctl rpc template -o=user.proto
|
|
|
|
+ ```
|
|
|
|
+
|
|
|
|
+ ```golang
|
|
|
|
+ syntax = "proto3";
|
|
|
|
+
|
|
|
|
+ package remote;
|
|
|
|
+
|
|
|
|
+ message Request {
|
|
|
|
+ // 用户名
|
|
|
|
+ string username = 1;
|
|
|
|
+ // 用户密码
|
|
|
|
+ string password = 2;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ message Response {
|
|
|
|
+ // 用户名称
|
|
|
|
+ string name = 1;
|
|
|
|
+ // 用户性别
|
|
|
|
+ string gender = 2;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ service User {
|
|
|
|
+ // 登录
|
|
|
|
+ rpc Login(Request)returns(Response);
|
|
|
|
+ }
|
|
|
|
+ ```
|
|
|
|
+* 生成rpc服务代码
|
|
|
|
+
|
|
|
|
+ ```
|
|
|
|
+ $ goctl rpc proto -src=user.proto
|
|
|
|
+ ```
|
|
|
|
+
|
|
|
|
+ 代码tree
|
|
|
|
+
|
|
|
|
+ ```
|
|
|
|
+ user
|
|
|
|
+ ├── etc
|
|
|
|
+ │ └── user.json
|
|
|
|
+ ├── internal
|
|
|
|
+ │ ├── config
|
|
|
|
+ │ │ └── config.go
|
|
|
|
+ │ ├── handler
|
|
|
|
+ │ │ ├── loginhandler.go
|
|
|
|
+ │ ├── logic
|
|
|
|
+ │ │ └── loginlogic.go
|
|
|
|
+ │ └── svc
|
|
|
|
+ │ └── servicecontext.go
|
|
|
|
+ ├── pb
|
|
|
|
+ │ └── user.pb.go
|
|
|
|
+ ├── shared
|
|
|
|
+ │ ├── mockusermodel.go
|
|
|
|
+ │ ├── types.go
|
|
|
|
+ │ └── usermodel.go
|
|
|
|
+ ├── user.go
|
|
|
|
+ └── user.proto
|
|
|
|
+
|
|
|
|
+ ```
|
|
# 准备工作
|
|
# 准备工作
|
|
|
|
+
|
|
* 安装了go环境
|
|
* 安装了go环境
|
|
* 安装了protoc&protoc-gen-go,并且已经设置环境变量
|
|
* 安装了protoc&protoc-gen-go,并且已经设置环境变量
|
|
-* mockgen(可选)
|
|
|
|
|
|
+* mockgen(可选,将移除)
|
|
|
|
+* 更多问题请见 <a href="#注意事项">注意事项</a>
|
|
|
|
|
|
# 用法
|
|
# 用法
|
|
|
|
+
|
|
|
|
+### rpc服务生成用法
|
|
|
|
+
|
|
```shell script
|
|
```shell script
|
|
$ goctl rpc proto -h
|
|
$ goctl rpc proto -h
|
|
```
|
|
```
|
|
@@ -91,27 +135,28 @@ OPTIONS:
|
|
--src value, -s value the file path of the proto source file
|
|
--src value, -s value the file path of the proto source file
|
|
--dir value, -d value the target path of the code,default path is "${pwd}". [option]
|
|
--dir value, -d value the target path of the code,default path is "${pwd}". [option]
|
|
--service value, --srv value the name of rpc service. [option]
|
|
--service value, --srv value the name of rpc service. [option]
|
|
- --shared value the dir of the shared file,default path is "${pwd}/shared. [option]"
|
|
|
|
|
|
+ --shared[已废弃] value the dir of the shared file,default path is "${pwd}/shared. [option]"
|
|
--idea whether the command execution environment is from idea plugin. [option]
|
|
--idea whether the command execution environment is from idea plugin. [option]
|
|
|
|
|
|
```
|
|
```
|
|
|
|
|
|
-* 参数说明
|
|
|
|
- * --src 必填,proto数据源,目前暂时支持单个proto文件生成,这里不支持(不建议)外部依赖
|
|
|
|
- * --dir 非必填,默认为proto文件所在目录,生成代码的目标目录
|
|
|
|
- * --service 服务名称,非必填,默认为proto文件所在目录名称,但是,如果proto所在目录为一下结构:
|
|
|
|
- ```shell script
|
|
|
|
- user
|
|
|
|
- ├── cmd
|
|
|
|
- │ └── rpc
|
|
|
|
- │ └── user.proto
|
|
|
|
- ```
|
|
|
|
- 则服务名称亦为user,而非proto所在文件夹名称了,这里推荐使用这种结构,可以方便在同一个服务名下建立不同类型的服务(api、rpc、mq等),便于代码管理与维护。
|
|
|
|
- * --shared 非必填,默认为$dir(xxx.proto)/shared,rpc client逻辑代码存放目录。
|
|
|
|
-
|
|
|
|
- > 注意:这里的shared文件夹名称将会是代码中的package名称。
|
|
|
|
-
|
|
|
|
- * --idea 非必填,是否为idea插件中执行,保留字段,终端执行可以忽略
|
|
|
|
|
|
+### 参数说明
|
|
|
|
+
|
|
|
|
+* --src 必填,proto数据源,目前暂时支持单个proto文件生成,这里不支持(不建议)外部依赖
|
|
|
|
+* --dir 非必填,默认为proto文件所在目录,生成代码的目标目录
|
|
|
|
+* --service 服务名称,非必填,默认为proto文件所在目录名称,但是,如果proto所在目录为一下结构:
|
|
|
|
+ ```shell script
|
|
|
|
+ user
|
|
|
|
+ ├── cmd
|
|
|
|
+ │ └── rpc
|
|
|
|
+ │ └── user.proto
|
|
|
|
+ ```
|
|
|
|
+ 则服务名称亦为user,而非proto所在文件夹名称了,这里推荐使用这种结构,可以方便在同一个服务名下建立不同类型的服务(api、rpc、mq等),便于代码管理与维护。
|
|
|
|
+* --shared[⚠️已废弃] 非必填,默认为$dir(xxx.proto)/shared,rpc client逻辑代码存放目录。
|
|
|
|
+
|
|
|
|
+ > 注意:这里的shared文件夹名称将会是代码中的package名称。
|
|
|
|
+
|
|
|
|
+* --idea 非必填,是否为idea插件中执行,保留字段,终端执行可以忽略
|
|
|
|
|
|
# 开发人员需要做什么
|
|
# 开发人员需要做什么
|
|
|
|
|
|
@@ -124,6 +169,10 @@ OPTIONS:
|
|
对于需要进行rpc mock的开发人员,在安装了`mockgen`工具的前提下可以在rpc的shared文件中生成好对应的mock文件。
|
|
对于需要进行rpc mock的开发人员,在安装了`mockgen`工具的前提下可以在rpc的shared文件中生成好对应的mock文件。
|
|
|
|
|
|
# 注意事项
|
|
# 注意事项
|
|
|
|
+* `google.golang.org/grpc`需要降级到v1.26.0,且protoc-gen-go版本不能高于v1.3.2(see [https://github.com/grpc/grpc-go/issues/3347](https://github.com/grpc/grpc-go/issues/3347))即
|
|
|
|
+ ```
|
|
|
|
+ replace google.golang.org/grpc => google.golang.org/grpc v1.26.0
|
|
|
|
+ ```
|
|
* proto不支持暂多文件同时生成
|
|
* proto不支持暂多文件同时生成
|
|
* proto不支持外部依赖包引入,message不支持inline
|
|
* proto不支持外部依赖包引入,message不支持inline
|
|
* 目前main文件、shared文件、handler文件会被强制覆盖,而和开发人员手动需要编写的则不会覆盖生成,这一类在代码头部均有
|
|
* 目前main文件、shared文件、handler文件会被强制覆盖,而和开发人员手动需要编写的则不会覆盖生成,这一类在代码头部均有
|
|
@@ -133,8 +182,42 @@ OPTIONS:
|
|
```
|
|
```
|
|
的标识,请注意不要将也写业务性代码写在里面。
|
|
的标识,请注意不要将也写业务性代码写在里面。
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+# 常见问题解决(go mod工程)
|
|
|
|
+
|
|
|
|
+* 错误一:
|
|
|
|
+
|
|
|
|
+ ```golang
|
|
|
|
+ pb/xx.pb.go:220:7: undefined: grpc.ClientConnInterface
|
|
|
|
+ pb/xx.pb.go:224:11: undefined: grpc.SupportPackageIsVersion6
|
|
|
|
+ pb/xx.pb.go:234:5: undefined: grpc.ClientConnInterface
|
|
|
|
+ pb/xx.pb.go:237:24: undefined: grpc.ClientConnInterface
|
|
|
|
+ ```
|
|
|
|
+ 解决方法:请将`protoc-gen-go`版本降至v1.3.2及一下
|
|
|
|
+
|
|
|
|
+* 错误二:
|
|
|
|
+
|
|
|
|
+ ```golang
|
|
|
|
+
|
|
|
|
+ # go.etcd.io/etcd/clientv3/balancer/picker
|
|
|
|
+ ../../../go/pkg/mod/go.etcd.io/etcd@v0.0.0-20200402134248-51bdeb39e698/clientv3/balancer/picker/err.go:25:9: cannot use &errPicker literal (type *errPicker) as type Picker in return argument:*errPicker does not implement Picker (wrong type for Pick method)
|
|
|
|
+ have Pick(context.Context, balancer.PickInfo) (balancer.SubConn, func(balancer.DoneInfo), error)
|
|
|
|
+ want Pick(balancer.PickInfo) (balancer.PickResult, error)
|
|
|
|
+ ../../../go/pkg/mod/go.etcd.io/etcd@v0.0.0-20200402134248-51bdeb39e698/clientv3/balancer/picker/roundrobin_balanced.go:33:9: cannot use &rrBalanced literal (type *rrBalanced) as type Picker in return argument:
|
|
|
|
+ *rrBalanced does not implement Picker (wrong type for Pick method)
|
|
|
|
+ have Pick(context.Context, balancer.PickInfo) (balancer.SubConn, func(balancer.DoneInfo), error)
|
|
|
|
+ want Pick(balancer.PickInfo) (balancer.PickResult, error)
|
|
|
|
+ #github.com/tal-tech/go-zero/rpcx/internal/balancer/p2c
|
|
|
|
+ ../../../go/pkg/mod/github.com/tal-tech/go-zero@v1.0.12/rpcx/internal/balancer/p2c/p2c.go:41:32: not enough arguments in call to base.NewBalancerBuilder
|
|
|
|
+ have (string, *p2cPickerBuilder)
|
|
|
|
+ want (string, base.PickerBuilder, base.Config)
|
|
|
|
+ ../../../go/pkg/mod/github.com/tal-tech/go-zero@v1.0.12/rpcx/internal/balancer/p2c/p2c.go:58:9: cannot use &p2cPicker literal (type *p2cPicker) as type balancer.Picker in return argument:
|
|
|
|
+ *p2cPicker does not implement balancer.Picker (wrong type for Pick method)
|
|
|
|
+ have Pick(context.Context, balancer.PickInfo) (balancer.SubConn, func(balancer.DoneInfo), error)
|
|
|
|
+ want Pick(balancer.PickInfo) (balancer.PickResult, error)
|
|
|
|
+ ```
|
|
|
|
+
|
|
|
|
+ 解决方法:
|
|
|
|
+
|
|
|
|
+ ```golang
|
|
|
|
+ replace google.golang.org/grpc => google.golang.org/grpc v1.26.0
|
|
|
|
+ ```
|