go-zero學習之RPC呼叫

charliecen發表於2021-10-13

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 協議》,轉載必須註明作者和本文連結

相關文章