• go-zero微服务的使用


    一、入门案例

    • 1、使用goland创建一个工程

    • 2、新建一个user.proto

      syntax = "proto3";
      
      package user;
      // 这个地方表示生成的go的包名叫user
      option go_package = "./user";
      
      message UserInfoRequest {
        int64 userId = 1;
      }
      
      message UserInfoResponse {
        int64 userId = 1;
        string username = 2;
      }
      
      
      message UserCreateRequest {
        string username = 1;
        string password = 2;
      }
      
      message UserCreateResponse {
        string message = 1;
      }
      
      // 定义两个方法
      service Users {
        rpc UserInfoById(UserInfoRequest) returns(UserInfoResponse);
        rpc CreateUser(UserCreateRequest) returns(UserCreateResponse);
      }
      
      
      // goctl rpc protoc user.proto --go_out=./types --go-grpc_out=./types --zrpc_out=.
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
    • 3、使用goctl执行生成对应的项目文件

      goctl rpc protoc user.proto --go_out=./types --go-grpc_out=./types --zrpc_out=.
      
      • 1
    • 4、安装依赖包

    • 5、运行文件go run user.go,不出意外的话肯定会启动后挂的,查看etc/user.yaml文件里面用etcd的服务,但是本地没启动etcd

    二、etcd的安装

    三、测试启动的rpc端口

    • 1、需要下载一个最新版的apifox(老版的不支持),创建一个grpc的项目

      在这里插入图片描述

    • 2、导入你刚刚写的proto文件

    在这里插入图片描述

    • 3、测试调用接口

    在这里插入图片描述

    • 4、在internal/logic/userinfobyidlogic.go里面补充代码,重启服务继续测试

      func (l *UserInfoByIdLogic) UserInfoById(in *user.UserInfoRequest) (*user.UserInfoResponse, error) {
      	// todo: add your logic here and delete this line
      
      	return &user.UserInfoResponse{
      		UserId:   in.UserId,
      		Username: "水痕",
      	}, nil
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

    四、rpc对接gorm数据库操作

    • 1、参考go-zero对数据库的操作,基本步骤都是一样的,这里就不继续重复的工作

    • 2、修改根据用户id查询用户数据方法

      func (l *UserInfoByIdLogic) UserInfoById(in *user.UserInfoRequest) (*user.UserInfoResponse, error) {
      	// todo: add your logic here and delete this line
          //userEntity := &model.UserEntity{}
      	//l.svcCtx.MySqlDb.Where("id = ?", in.UserId).First(&userEntity)
          
      	userEntity, err := dao.Use(l.svcCtx.MySqlDb).UserEntity.WithContext(l.ctx).Where(dao.Use(l.svcCtx.MySqlDb).UserEntity.ID.Eq(in.UserId)).First()
      	fmt.Println(userEntity, "获取到的数据")
      	return &user.UserInfoResponse{
      		UserId:   userEntity.ID,
      		Username: userEntity.Username,
      	}, err
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    • 3、继续测试下创建用户的方法

      func (l *CreateUserLogic) CreateUser(in *user.UserCreateRequest) (*user.UserCreateResponse, error) {
      	// todo: add your logic here and delete this line
      	if err := dao.Use(l.svcCtx.MySqlDb).UserEntity.Create(&model.UserEntity{
      		Username: in.Username,
      		Password: in.Password,
      	}); err != nil {
      		return &user.UserCreateResponse{
      			Message: "创建失败",
      		}, nil
      	}
      	return &user.UserCreateResponse{
      		Message: "创建成功",
      	}, nil
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

    五、api对接rpc接口

    • 1、创建一个项目分别创建两个文件夹rpcapi

    • 2、rpc项目和上面介绍的一样的,这里就不继续重复介绍,执行转换脚本

      goctl rpc protoc user.proto --go_out=types --go-grpc_out=types --zrpc_out=.
      
      • 1
    • 3、创建一个user.api文件

      type CreateRequest {
          Username string `json:"username"`
          Password string `json:"password"`
      }
      
      type CreateResponse {
          Message string `json:"message"`
      }
      
      type UserInfoRequest {
          Id int64 `path:"id"`
      }
      type UserInfoResponse {
          Id int64 `json:"id"`
          Username string `json:"username"`
      }
      
      
      // 定义要被方法的方法
      service users {
          @handler create
          post /api/users (CreateRequest) returns (CreateResponse)
      
          @handler userInfo
          get /api/users/:id (UserInfoRequest) returns (UserInfoResponse)
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
    • 4、在api/etc/users.yaml文件中添加rpc中配置

      Name: users
      Host: 0.0.0.0
      Port: 8888
      # 直接引入etcd的地址就可以,Key直接查看rpc/etc/user.yaml,并且要保持一致
      UserRpc:
        Etcd:
          Hosts:
            - 127.0.0.1:2379
          Key: user.rpc
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • 5、在api/internal/config/config.go中添加user.rpc的配置

      package config
      
      import (
      	"github.com/zeromicro/go-zero/rest"
      	"github.com/zeromicro/go-zero/zrpc"
      )
      
      type Config struct {
      	rest.RestConf
      	UserRpc zrpc.RpcClientConf
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 6、 api/internal/svc/servicecontext.go添加rpc的服务配置

      package svc
      
      import (
      	"github.com/zeromicro/go-zero/zrpc"
      	"zero_demo06_rpc_api/api/internal/config"
      	"zero_demo06_rpc_api/rpc/userclient"
      )
      
      type ServiceContext struct {
      	Config  config.Config
      	UserRpc userclient.User
      }
      
      func NewServiceContext(c config.Config) *ServiceContext {
      	return &ServiceContext{
      		Config:  c,
      		UserRpc: userclient.NewUser(zrpc.MustNewClient(c.UserRpc)),
      	}
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    • 7、在api/internal/logic里面写业务逻辑

      func (l *UserInfoLogic) UserInfo(req *types.UserInfoRequest) (resp *types.UserInfoResponse, err error) {
      	// todo: add your logic here and delete this line
      	userInfo, err := l.svcCtx.UserRpc.UserInfoById(l.ctx, &user.UserInfoRequest{UserId: req.Id})
      	if err != nil {
      		return &types.UserInfoResponse{}, err
      	}
      	return &types.UserInfoResponse{
      		Id:       userInfo.UserId,
      		Username: userInfo.Username,
      	}, nil
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      func (l *CreateLogic) Create(req *types.CreateRequest) (resp *types.CreateResponse, err error) {
      	// todo: add your logic here and delete this line
      	createUser, err := l.svcCtx.UserRpc.CreateUser(l.ctx, &user.UserCreateRequest{
      		Username: req.Username,
      		Password: req.Password,
      	})
      	if err != nil {
      		return nil, err
      	}
      	return &types.CreateResponse{
      		Message: createUser.Message,
      	}, nil
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    • 8、运行2个项目,前端直接访问api层接口

    • 9、本案例代码

  • 相关阅读:
    pytorch基础学习(4)
    Java NIO详解:深入理解非阻塞式网络编程
    CSS 毛玻璃特效运用目录
    超级适合小白!学Java必读书籍,强烈推荐
    视频怎么批量压缩?5个好用的电脑软件和在线网站
    盘一盘那些年我们使用的Java
    基于51单片机的智能病房呼叫系统的设计与实现
    基于JAVA商超销售系统计算机毕业设计源码+数据库+lw文档+系统+部署
    测试驱动开发TDD
    数据通信网络之IPv6以太网二层交换
  • 原文地址:https://blog.csdn.net/kuangshp128/article/details/134488316