第五届青训营后端第七天学习笔记| 青训营笔记

62 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天

一、本堂课重点内容:

  • rpc-user-info讲解
  • 个人小结

本文通过项目来进行案例讲解。

二、讲解

本项目rpc框架选用Kitex,并且通过代码生成器进行生成,因此该微服务结构具有Kitex特色,根据Kitex官方文档,开发者只需要关注handler的业务逻辑即可,而负责这块的同学为了代码进一步抽象,将业务逻辑进一步抽象,放到了logic下,下面则会对此进行详细介绍。

  • main函数:包括服务注册、服务端生成。
func main() {
   // 日志
   f, err := os.OpenFile("./user-info.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
   if err != nil {
      panic(err)
   }
   defer f.Close()
   klog.SetOutput(f)
   // 服务注册
   svr := userInfoPb.NewServer(
      new(UserInfoImpl),
      server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: "userInfoImpl"}),
      server.WithRegistry(registry.NewNacosRegistry(nacos.Cli)),
      server.WithServiceAddr(&net.TCPAddr{Port: 50051}),
   )
   if err := svr.Run(); err != nil {
      log.Println("server stopped with error:", err)
   } else {
      log.Println("server stopped")
   }
}
  • Handler:这里的代码则是rpc能够调用的代码
func (s *UserInfoImpl) Register(ctx context.Context, req *userInfoPb.RegisterReq) (resp *userInfoPb.RegisterResp, err error) {
   // TODO: Your code here...
   return logic.Register(req)
}

// Login implements the UserInfoImpl interface.
func (s *UserInfoImpl) Login(ctx context.Context, req *userInfoPb.LoginReq) (resp *userInfoPb.LoginResp, err error) {
   // TODO: Your code here...
   return logic.Login(req)
}

// Info implements the UserInfoImpl interface.
func (s *UserInfoImpl) Info(ctx context.Context, req *userInfoPb.UserInfoReq) (resp *userInfoPb.UserInfoResp, err error) {
   // TODO: Your code here...
   return logic.Info(ctx, req)
}

// ActionDB implements the UserInfoImpl interface.
func (s *UserInfoImpl) ActionDB(ctx context.Context, req *userInfoPb.ActionDBReq) (resp *userInfoPb.ActionDBResp, err error) {
   // TODO: Your code here...
   return logic.ActionDB(ctx, req)
}

// BatchInfo implements the UserInfoImpl interface.
func (s *UserInfoImpl) BatchInfo(ctx context.Context, req *userInfoPb.BatchUserReq) (resp *userInfoPb.BtachUserResp, err error) {
   // TODO: Your code here...
   return logic.BatchInfo(ctx, req)
  • logic:具体的业务逻辑实现,以登录为例。其他的根据接口的不同,选择不同的储存策略,例如修改信息为了保证数据库和缓存一致性,采用双删策略。为了缓解io瓶颈,对于用户信息采用缓存策略。
func Login(req *userInfoPb.LoginReq) (resp *userInfoPb.LoginResp, err error) {
   resp = new(userInfoPb.LoginResp)
   user := models.UserInfo{}
   userReq := models.UserInfo{UserName: req.UserName, Password: req.Password}
   err = models.DB.Where("user_name = ?", userReq.UserName).First(&user).Error
   if err != nil {
      resp.StatusCode = 1
      resp.StatusMsg = "查询失败"
      return resp, err
   }
   isValid := utils.ValidPassword(userReq.Password, user.Salt, user.Password)
   if !isValid {
      resp.StatusCode = 1
      resp.StatusMsg = "密码错误"
      return resp, err
   }
   token, err := utils.GenerateToken(user.ID, user.UserName)
   if err != nil {
      resp.StatusCode = 1
      resp.StatusMsg = "生成token失败"
      return resp, err
   }
   resp.StatusCode = 0
   resp.StatusMsg = "查询成功"
   resp.UserId = uint64(int64(user.ID))
   resp.Token = token
   return resp, nil
}

二、引用参考: