go-zero微服务试用

参考地址:https://go-zero.dev/cn/docs/quick-start/micro-service#%E5%88%9B%E5%BB%BAuser-rpc%E6%9C%8D%E5%8A%A1

go-zero介绍

go-zero(收录于 CNCF 云原生技术全景图:https://landscape.cncf.io/?selected=go-zero)是一个集成了各种工程实践的 web 和 rpc 框架。通过弹性设计保障了大并发服务端的稳定性,经受了充分的实战检验。

go-zero 包含极简的 API 定义和生成工具 goctl,可以根据定义的 api 文件一键生成 Go, iOS, Android, Kotlin, Dart, TypeScript, JavaScript 代码,并可直接运行。

使用 go-zero 的好处:

  • 轻松获得支撑千万日活服务的稳定性
  • 内建级联超时控制、限流、自适应熔断、自适应降载等微服务治理能力,无需配置和额外代码
  • 微服务治理中间件可无缝集成到其它现有框架使用
  • 极简的 API 描述,一键生成各端代码
  • 自动校验客户端请求参数合法性
  • 大量微服务治理和并发工具包

1.根据官方文档快速创建微服务
我们首先在go项目目录创建go-zero-demo

  mkdir go-zero-demo
  cd go-zero-demo
  go mod init go-zero-demo

2.创建user rpc服务

2.1创建user rpc目录

 mkdir -p mall/user/rpc

2.2添加user.proto文件,增加getUser方法

vim mall/user/rpc/user.proto

2.3增加如下代码:

    syntax = "proto3";
    package user;
    // protoc-gen-go 版本大于1.4.0, proto文件需要加上go_package,否则无法生成
    option go_package = "./user";
    message IdRequest {
        string id = 1;
    }
    message UserResponse {
      // 用户id
      string id = 1;
      // 用户名称
      string name = 2;
      // 用户性别
      string gender = 3;
    }
    service User {
        rpc getUser(IdRequest) returns(UserResponse);
    }

2.4生成代码

  cd mall/user/rpc
  goctl rpc protoc user.proto --go_out=./types --go-grpc_out=./types --zrpc_out=.

2.5填充业务逻辑

 vim internal/logic/getuserlogic.go


package logic
import (
  "context"
  "go-zero-demo/mall/user/rpc/internal/svc"
  "go-zero-demo/mall/user/rpc/types/user"
  "github.com/zeromicro/go-zero/core/logx"
)
type GetUserLogic struct {
  ctx context.Context
  svcCtx *svc.ServiceContext
  logx.Logger
}
func NewGetUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserLogic {
  return &GetUserLogic{
  ctx: ctx,
  svcCtx: svcCtx,
  Logger: logx.WithContext(ctx),
  }
}
func (l *GetUserLogic) GetUser(in *user.IdRequest) (*user.UserResponse, error) {
  return &user.UserResponse{
  Id: "1",    
  Name: "test",
  }, nil
}

3创建order api服务#

3.1创建 order api目录

回到 go-zero-demo/mall 目录

mkdir -p order/api && cd order/api

3.1添加api文件

 vim order.api


type(
  OrderReq {
      Id string `path:"id"`
  }
  OrderReply {
      Id string `json:"id"`
      Name string `json:"name"`
  }
)
service order {
  @handler getOrder
  get /api/order/get/:id (OrderReq) returns (OrderReply)
}

3.2生成order服务

 goctl api go -api order.api -dir .

3.3添加user rpc配置

 vim internal/config/config.go

补充内容

package config
import (
  "github.com/zeromicro/go-zero/zrpc"
  "github.com/zeromicro/go-zero/rest"
)

type Config struct {
  rest.RestConf
  UserRpc zrpc.RpcClientConf
}

3.4添加yaml配置

 vim etc/order.yaml 


Name: order
Host: 0.0.0.0
Port: 8888
UserRpc:
Etcd:
Hosts:
- 127.0.0.1:2379
Key: user.rpc

3.5完善服务依赖
这里官方文档用的是user,我本地使用发现生成的代码没有user只有userclient极有可能是官方文档未及时更新。

vim internal/svc/servicecontext.go

补充内容

package svc

import (

"go-zero-demo/mall/order/api/internal/config"
"go-zero-demo/mall/user/rpc/userclient"
"github.com/zeromicro/go-zero/zrpc"
)
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)),
}
}

3.6给 getorderlogic 添加业务逻辑

vim internal/logic/getorderlogic.go

补充内容

package logic
import (
  "context"
  "errors"
  "go-zero-demo/mall/order/api/internal/svc"
  "go-zero-demo/mall/order/api/internal/types"
  "go-zero-demo/mall/user/rpc/types/user"
  "github.com/zeromicro/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.OrderReply, error) {
    user, err := l.svcCtx.UserRpc.GetUser(l.ctx, &user.IdRequest{
    Id: "1",
    })

    if err != nil {
    return nil, err
    }
    if user.Name != "test" {
    return nil, errors.New("用户不存在")
    }

    return &types.OrderReply{
    Id: req.Id,
    Name: "test order",
    }, nil

}

4.启动服务并验证#

4.1启动etcd
这里没有etcd服务需要自己安装

 etcd

4.2下载依赖

在 go-zero-demo 目录下

 go mod tidy

4.3启动user rpc

在 mall/user/rpc 目录

 go run user.go -f etc/user.yaml

如果出现以下错误,就是没有启动etcd

4.4启动order api

在 mall/order/api 目录

 go run order.go -f etc/order.yaml

4.5访问order api

 curl -i -X GET http://localhost:8888/api/order/get/1