创建项目案例01的ucenter的grpc服务文件夹
一. 配置文件
1./etc/config.yaml文件名, 以及内容(安装和部署etcd服务发现)
Name: ucenter.rpc
ListenOn: 0.0.0.0:8081
Etcd:
Hosts:
- 42.193.152.252:2379
Key: ucenter.rpc
Token: tkn
DbMysql:
Host: 47.120.55.99
Port: 3306
Username: root
Password: chenhaifeng
Databases: go_netdisk
CacheRedis:
Host: "47.120.55.99:6379"
Pass: chenhaifeng
Type: node
2.main.go文件内同步文件名
var configFile = flag.String("f", "etc/config.yaml", "the config file")
3.internal/config.go文件
package config
import (
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/zrpc"
)
type Config struct {
zrpc.RpcServerConf
DbMysql MysqlConf
CacheRedis redis.RedisConf
}
type MysqlConf struct {
Host string
Port int
Username string
Password string
Databases string
}
type RedisConf struct {
Host string
Pass string
Type string
}
4.internal/svc/service_context.go服务的上下文
package svc
import (
"ucenter/internal/config"
"github.com/zeromicro/go-zero/core/stores/redis"
)
type ServiceContext struct {
Config config.Config
Redis redis.Redis
}
func NewServiceContext(c config.Config) *ServiceContext {
rds := redis.MustNewRedis(c.CacheRedis)
return &ServiceContext{
Config: c,
Redis: *rds,
}
}
5.服务主文件 internal/server/register_srever.go
package server
import (
"context"
"ucenter/internal/logic"
"ucenter/internal/svc"
"grpc-common/ucenter/types/register"
)
type RegisterServer struct {
svcCtx *svc.ServiceContext
register.UnimplementedRegisterServer
}
func NewRegisterServer(svcCtx *svc.ServiceContext) *RegisterServer {
return &RegisterServer{
svcCtx: svcCtx,
}
}
// 定义一个 SayHello 一元 rpc 方法,请求体和响应体必填。
func (s *RegisterServer) RegisterByPhone(ctx context.Context, in *register.RegReq) (*register.RegRes, error) {
l := logic.NewRegisterByLogic(ctx, s.svcCtx)
return l.RegisterByPhone(in)
}
func (s *RegisterServer) SendCode(ctx context.Context, in *register.CodeReq) (*register.CodeRes, error) {
l := logic.NewRegisterByLogic(ctx, s.svcCtx)
return l.SendCode(in)
}
6.服务的接口文件 internal/logic/register_logic.go
package logic
import (
"context"
"mscoin/mscoin-common/tools"
"time"
"grpc-common/ucenter/types/register"
"ucenter/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type RegisterByLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewRegisterByLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegisterByLogic {
return &RegisterByLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
// 定义一个 SayHello 一元 rpc 方法,请求体和响应体必填。
func (l *RegisterByLogic) RegisterByPhone(in *register.RegReq) (*register.RegRes, error) {
// todo: add your logic here and delete this line
logx.Info("ucenter 执行了 grpc 注册接口")
return ®ister.RegRes{}, nil
}
func (l *RegisterByLogic) SendCode(in *register.CodeReq) (*register.CodeRes, error) {
code := tools.Rand4Num()
// 发送验证码(掠过)
go func() {
logx.Info("调用短信平台发送验证码成功")
}()
logx.Infof("验证码为:%s \n", code)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ok, err := l.svcCtx.Redis.SetnxExCtx(ctx, "code", code, 120)
if err != nil {
return ®ister.CodeRes{}, err
}
if ok {
logx.Info("写入验证码成功")
}
return ®ister.CodeRes{}, nil
}
二. 启动微服务时运行流程
- 读取配置文件
- 根据读取的配置yaml, 先创建服务结构体(redis, mysql, 等待连接)
- 根据读取的配置yaml, 注册到etcd服务发现
- 根据proto生成的go文件里注册方法, 绑定生成的server服务结构体
- 启动
main.go
func main() {
flag.Parse()
// 1. 读取配置文件
var c config.Config
conf.MustLoad(*configFile, &c)
// 2. 根据读取的配置, 创建服务上下文结构体
ctx := svc.NewServiceContext(c)
// 3. 根据读取的配置, 应该是注册当前的grpc服务到etcd服务发现里面
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
// 4. 这里register是生成的grpc的go文件, 再创建当前注册服务结构体对象
register.RegisterRegisterServer(grpcServer, server.NewRegisterServer(ctx))
if c.Mode == service.DevMode || c.Mode == service.TestMode {
reflection.Register(grpcServer)
}
})
defer s.Stop()
// 5. 启动
fmt.Printf("Starting rpc server at %s...\n", c.ListenOn)
s.Start()
}
三. 当请求到来时
1.先到4那里, server<服务结构体>绑定的 RegisterByPhone服务方法 2.方法内调用NewRegisterByLogic()创建<接口结构体>
package server
import (
"context"
"ucenter/internal/logic"
"ucenter/internal/svc"
"grpc-common/ucenter/types/register"
)
type RegisterServer struct {
svcCtx *svc.ServiceContext
register.UnimplementedRegisterServer
}
func NewRegisterServer(svcCtx *svc.ServiceContext) *RegisterServer {
return &RegisterServer{
svcCtx: svcCtx,
}
}
// 定义一个 SayHello 一元 rpc 方法,请求体和响应体必填。
func (s *RegisterServer) RegisterByPhone(ctx context.Context, in *register.RegReq) (*register.RegRes, error) {
l := logic.NewRegisterByLogic(ctx, s.svcCtx)
return l.RegisterByPhone(in)
}
func (s *RegisterServer) SendCode(ctx context.Context, in *register.CodeReq) (*register.CodeRes, error) {
l := logic.NewRegisterByLogic(ctx, s.svcCtx)
return l.SendCode(in)
}
3.运行<接口结构体>绑定的接口方法RegisterByPhone()
package logic
import (
"context"
"mscoin/mscoin-common/tools"
"time"
"grpc-common/ucenter/types/register"
"ucenter/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type RegisterByLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewRegisterByLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegisterByLogic {
return &RegisterByLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
// 定义一个 SayHello 一元 rpc 方法,请求体和响应体必填。
func (l *RegisterByLogic) RegisterByPhone(in *register.RegReq) (*register.RegRes, error) {
// todo: add your logic here and delete this line
logx.Info("ucenter 执行了 grpc 注册接口")
return ®ister.RegRes{}, nil
}
func (l *RegisterByLogic) SendCode(in *register.CodeReq) (*register.CodeRes, error) {
code := tools.Rand4Num()
// 发送验证码(掠过)
go func() {
logx.Info("调用短信平台发送验证码成功")
}()
logx.Infof("验证码为:%s \n", code)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ok, err := l.svcCtx.Redis.SetnxExCtx(ctx, "code", code, 120)
if err != nil {
return ®ister.CodeRes{}, err
}
if ok {
logx.Info("写入验证码成功")
}
return ®ister.CodeRes{}, nil
}
4.返回