rpc生成多分组服务
参考文档:
https://go-zero.dev/docs/tutorials/proto/services/group
服务分组描述
在 go-zero 中,我们通过在 proto 文件中以 service 为维度来进行文件分组,我们可以在 proto 文件中定义多个 service,每个 service 都会生成一个独立的文件夹,这样就可以将不同的服务进行分组,从而提高代码的可读性和可维护性。
除了 proto 文件中定义了 service 外,分组与否还需要在 goctl 中控制,生成带分组或者不带分组的代码取决于开发者,我们通过示例来演示一下。
操作步骤
- 定义proto文件
- 命令生成文件
- main文件注册service服务
- 编写业务逻辑
- 启动文件
proto文件定义
首先,我们需要在 proto 文件中定义多个 service
syntax = "proto3";
package user;
option go_package = "github.com/example/user";
message LoginReq{}
message LoginResp{}
message UserInfoReq{}
message UserInfoResp{}
message UserInfoUpdateReq{}
message UserInfoUpdateResp{}
message UserListReq{}
message UserListResp{}
service UserService{
rpc Login (LoginReq) returns (LoginResp);
rpc UserInfo (UserInfoReq) returns (UserInfoResp);
rpc UserInfoUpdate (UserInfoUpdateReq) returns (UserInfoUpdateResp);
rpc UserList (UserListReq) returns (UserListResp);
}
message UserRoleListReq{}
message UserRoleListResp{}
message UserRoleUpdateReq{}
message UserRoleUpdateResp{}
message UserRoleInfoReq{}
message UserRoleInfoResp{}
message UserRoleAddReq{}
message UserRoleAddResp{}
message UserRoleDeleteReq{}
message UserRoleDeleteResp{}
service UserRoleService{
rpc UserRoleList (UserRoleListReq) returns (UserRoleListResp);
rpc UserRoleUpdate (UserRoleUpdateReq) returns (UserRoleUpdateResp);
rpc UserRoleInfo (UserRoleInfoReq) returns (UserRoleInfoResp);
rpc UserRoleAdd (UserRoleAddReq) returns (UserRoleAddResp);
rpc UserRoleDelete (UserRoleDeleteReq) returns (UserRoleDeleteResp);
}
message UserClassListReq{}
message UserClassListResp{}
message UserClassUpdateReq{}
message UserClassUpdateResp{}
message UserClassInfoReq{}
message UserClassInfoResp{}
message UserClassAddReq{}
message UserClassAddResp{}
message UserClassDeleteReq{}
message UserClassDeleteResp{}
service UserClassService{
rpc UserClassList (UserClassListReq) returns (UserClassListResp);
rpc UserClassUpdate (UserClassUpdateReq) returns (UserClassUpdateResp);
rpc UserClassInfo (UserClassInfoReq) returns (UserClassInfoResp);
rpc UserClassAdd (UserClassAddReq) returns (UserClassAddResp);
rpc UserClassDelete (UserClassDeleteReq) returns (UserClassDeleteResp);
}
生成代码
通过 -m 指定 goctl 生成分组的代码
$ goctl rpc protoc user.proto –go_out=. –go-grpc_out=. –zrpc_out=. -m
我们来看一下带分组的情况下,goctl 生成的代码结构:
# 通过 -m 指定 goctl 生成分组的代码
$ goctl rpc protoc user.proto --go_out=. --go-grpc_out=. --zrpc_out=. -m
$ tree
.
├── client
│ ├── userclassservice
│ │ └── userclassservice.go
│ ├── userroleservice
│ │ └── userroleservice.go
│ └── userservice
│ └── userservice.go
├── etc
│ └── user.yaml
├── github.com
│ └── example
│ └── user
│ ├── user.pb.go
│ └── user_grpc.pb.go
├── go.mod
├── internal
│ ├── config
│ │ └── config.go
│ ├── logic
│ │ ├── userclassservice
│ │ │ ├── userclassaddlogic.go
│ │ │ ├── userclassdeletelogic.go
│ │ │ ├── userclassinfologic.go
│ │ │ ├── userclasslistlogic.go
│ │ │ └── userclassupdatelogic.go
│ │ ├── userroleservice
│ │ │ ├── userroleaddlogic.go
│ │ │ ├── userroledeletelogic.go
│ │ │ ├── userroleinfologic.go
│ │ │ ├── userrolelistlogic.go
│ │ │ └── userroleupdatelogic.go
│ │ └── userservice
│ │ ├── loginlogic.go
│ │ ├── userinfologic.go
│ │ ├── userinfoupdatelogic.go
│ │ └── userlistlogic.go
│ ├── server
│ │ ├── userclassservice
│ │ │ └── userclassserviceserver.go
│ │ ├── userroleservice
│ │ │ └── userroleserviceserver.go
│ │ └── userservice
│ │ └── userserviceserver.go
│ └── svc
│ └── servicecontext.go
├── user.go
└── user.proto
19 directories, 28 files
在 user.go 中注册服务
// 引入包
import (
userclassservice "ytss_go_zero/app/core/cmd/rpc/internal/server/userclassservice"
userroleservice "ytss_go_zero/app/core/cmd/rpc/internal/server/userroleservice"
userservice "ytss_go_zero/app/core/cmd/rpc/internal/server/userservice"
)
func main() {
flag.Parse()
var c config.Config
conf.MustLoad(*configFile, &c)
ctx := svc.NewServiceContext(c)
//注册服务
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
pb.RegisterUseClassClassServer(grpcServer, testserviceServer.NewUserClassServiceServer(ctx))
pb.RegisterRoleServiceServer(grpcServer, userserviceServer.NewRoleerviceServer(ctx))
pb.RegisterUserServiceServer(grpcServer, authgroupservice.NewUserServiceServer(ctx))
if c.Mode == service.DevMode || c.Mode == service.TestMode {
reflection.Register(grpcServer)
}
})
defer s.Stop()
fmt.Printf("Starting rpc server at %s...\n", c.ListenOn)
s.Start()
}
启动服务
go run user.go -f ./etc/user.yaml
api调用rpc步骤
- 修改
NewServiceContext
loginc
中调用
app/core/cmd/api/internal/logic/authGroup/update_auth_group_logic.go
实际操作
- 修改service_context
app/core/cmd/api/internal/svc/service_context.go
import (
"ytss_go_zero/app/core/cmd/rpc/client/testservice"
)
type ServiceContext struct {
CoreRpcAuthGroupService authgroupservice.AuthGroupService
}
func NewServiceContext(c config.Config) *ServiceContext {
// 初始化业务redis驱动
var rdbConf redis.Options
copier.Copy(&rdbConf, &c.RedisDB)
//// 初始化go-zero redis驱动
//var zrdbConf zredis.RedisConf
//copier.Copy(&zrdbConf, &c.Redis)
// 创建一个根Context
rootCtx := utils.NewKeyValueContext(context.Background())
// 测试上下文件
//rootCtx.Set("redisToken", "someToken")
//if token, ok := rootCtx.Get("redisToken"); ok {
// fmt.Println("Redis Token:", token)
//}
return &ServiceContext{
Config: c,
//Auth: middleware.NewAuthMiddleware().Handle,
TokenAuth: middleware.NewTokenAuthMiddleware(rootCtx).Handle,
RootCtx: rootCtx,
RDB: models.InitRedis(rdbConf),
//RDBZ: models.InitRedisGoZero(zrdbConf),
// 测试服务
CoreRpcTestService: testservice.NewTestService(zrpc.MustNewClient(c.CoreRpcConf)),
// 用户服务
CoreRpcUserService: userservice.NewUserService(zrpc.MustNewClient(c.CoreRpcConf)),
//CoreRpcUserService: userservice.NewUserService(zrpc.MustNewClient(c.CoreRpcConf, zrpc.WithUnaryClientInterceptor(HeaderStreamInterceptor))),
// 角色组服务
CoreRpcAuthGroupService: authgroupservice.NewAuthGroupService(zrpc.MustNewClient(c.CoreRpcConf)),
}
}
loginc
中调用
import (
"ytss_go_zero/app/core/cmd/rpc/client/testservice"
)
func (l *PingRpcLogic) PingRpc(req *types.PingReq) (resp *types.PingResp, err error) {
//if req.Id == 0 {
// err = errors.New("req.id is required")
//}
if err != nil {
return nil, err
}
// 调用rpc入参
pongReq := testservice.PongReq{}
err = copier.Copy(&pongReq, req)
if err != nil {
return nil, err
}
pong, err := l.svcCtx.CoreRpcTestService.Pong(l.ctx, &pongReq)
if err != nil {
//return nil, err
//参数1,返回给前端,参数2,打印到日志到控制台
return nil, errors.Wrapf(xerr.NewErrMsg("add address fail"), "add address rpc AddUserAddress fail req: %+v , err : %v ", req, err)
}
resp = &types.PingResp{
Msg: pong.Msg,
}
return
}
作者:海马 创建时间:2024-08-10 17:02
最后编辑:海马 更新时间:2024-12-22 19:32
最后编辑:海马 更新时间:2024-12-22 19:32