go-zero学习之RPC调用

RPC服务调用

go-zero中,使用是的zrpc来进行服务间的通信,zrpc是基于grpc

这里的流程是user-api调用order-rpc服务

添加api接口文件
syntax = "v1"

info(
    title: "用户管理"
    desc: "用户管理"
    author: "charlie"
    email: "cenhuqing@163.com"
    version: "1.0"
)

type (
    RegisterReq {
        Username string `json:"username"`
        Password string `json:"password"`
        Age      int    `json:"age"`
        Gender   string `json:"gender"`
    }

    RegisterResp {
        Msg string `json:"msg"`
    }

    LoginReq {
        Username string `json:"username"`
        Password string `json:"password"`
    }

    LoginResp {
        Username     string `json:"Username"`
        Age          int    `json:"age"`
        Gender       string `json:"gender"`
        Token        string `json:"token"`
        ExpireTime   int64  `json:"expire_time"`
        RefreshAfter int64  `json:"refreshAfter"`
    }

    OrderReq {
        Id int64 `json:"id"`
    }

    OrderResp {
        Id      int64 `json:"id"`
        UserId  int64 `json:"userId"`
        Money   int64 `json:"money"`
        GoodsId int64 `json:"goodsId"`
    }
)

// 用户接口
service user-api {
    // 注册
    @handler signIn
    // 请求方式, 路由地址, (请求数据), (响应数据)
    post /user/register (RegisterReq) returns (RegisterResp)
    // 登录
    @handler getUser
    post /user/login (LoginReq) returns(LoginResp)
    // 获取订单信息
    @handler getOrder
    post /order/info (OrderReq) returns (OrderResp)
}
生成api服务代码
❯ goctl.exe api go -api  user.api -dir .
etc/user-api.yaml exists, ignored generation
internal/config/config.go exists, ignored generation
user.go exists, ignored generation
internal/svc/servicecontext.go exists, ignored generation
internal/handler/signinhandler.go exists, ignored generation
internal/handler/getuserhandler.go exists, ignored generation
internal/logic/signinlogic.go exists, ignored generation
internal/logic/getuserlogic.go exists, ignored generation
Done.
添加配置
> vim .\service\user\rpc\etc\user.yaml

OrderRpc:
  Etcd:
    Hosts:
      - 127.0.0.1:2379
    Key: order.rpc
声明配置类型
> vim .\service\user\rpc\internal\config\config.go

package config

import (
    "github.com/tal-tech/go-zero/core/stores/cache"
    "github.com/tal-tech/go-zero/rest"
    "github.com/tal-tech/go-zero/zrpc"
)

type Config struct {
    rest.RestConf
    Mysql struct{
        DataSource string
    }
    CacheRedis cache.CacheConf
    Jwt struct{
        AccessExpire int64
        AccessSecret string
    }
    OrderRpc zrpc.RpcClientConf
}

填充数据库依赖
> vim .\service\user\rpc\internal\svc\servicecontext.go

package svc

import (
    "github.com/tal-tech/go-zero/core/stores/sqlx"
    "github.com/tal-tech/go-zero/zrpc"
    "go-zero-demo1/service/order/rpc/orderclient"
    "go-zero-demo1/service/user/api/internal/config"
    "go-zero-demo1/service/user/model"
)

type ServiceContext struct {
    Config config.Config
    UserModel model.UserModel
    OrderRpc orderclient.Order
}

func NewServiceContext(c config.Config) *ServiceContext {
    conn := sqlx.NewMysql(c.Mysql.DataSource)
    return &ServiceContext{
        Config: c,
        UserModel: model.NewUserModel(conn),
        OrderRpc: orderclient.NewOrder(zrpc.MustNewClient(c.OrderRpc)),
    }
}

填充逻辑
> vim .\service\user\rpc\internal\logic\getorderlogic.go

package logic

import (
    "context"
    "fmt"
    "go-zero-demo1/service/order/rpc/orderclient"

    "go-zero-demo1/service/user/api/internal/svc"
    "go-zero-demo1/service/user/api/internal/types"

    "github.com/tal-tech/go-zero/core/logx"
)

type GetOrderLogic struct {
    logx.Logger
    ctx    context.Context
    svcCtx *svc.ServiceContext
}

func NewGetOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) GetOrderLogic {
    return GetOrderLogic{
        Logger: logx.WithContext(ctx),
        ctx:    ctx,
        svcCtx: svcCtx,
    }
}

func (l *GetOrderLogic) GetOrder(req types.OrderReq) (*types.OrderResp, error) {
    // todo: add your logic here and delete this line
    orderInfo, err := l.svcCtx.OrderRpc.GetOrder(l.ctx, &orderclient.OrderReq{
        Id: req.Id,
    })
    fmt.Println(orderInfo)
    if err != nil {
        return nil, err
    }
    return &types.OrderResp{
        Id: orderInfo.Id,
        UserId: orderInfo.UserId,
        Money: orderInfo.Money,
        GoodsId: orderInfo.GoodsId,
    }, nil
}

注意:上面配置文件中存在etcd,所以这里需要运行etcd服务

运行etcd服务

etcd 是一种开源的分布式统一键值存储,用于分布式系统或计算机集群的共享配置、服务发现和的调度协调。

下载地址

我这里是windows系统,所以下载的是etcd-v3.5.0-windows-amd64.zip,下载完成后,解压出运行etcd.exe,至此etcd服务运行起来了

启动rpc服务
❯ go run .\user.go -f .\etc\user-api.yaml
go: go-zero-demo1/service/user/rpc/user: package google.golang.org/grpc imported from implicitly required module; to add missing requirements, run:
        go get google.golang.org/grpc@v1.39.0

上述问题是由于包为找到,所以自动加载依赖,需要运行以下命令

> go mod tidy

再次启动服务

❯ go run .\user.go -f .\etc\user-api.yaml
Starting server at 0.0.0.0:8888...

至此user api 服务已经启动,下面是来调用订单服务

测试请求
❯ curl -i -X POST http://localhost:8888/order/info -H 'content-type: application/json' -d '{"id":1}'
HTTP/1.1 200 OK
Content-Type: application/json
X-Trace-Id: 3eab0a07374d5a24
Date: Wed, 13 Oct 2021 08:12:52 GMT
Content-Length: 50

{"id":1,"userId":1,"money":1000,"goodsId":1231313}
本作品采用《CC 协议》,转载必须注明作者和本文链接
charliecen
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!