您现在的位置是:首页 >技术教程 >go-zero快速开发单体服务和微服务网站首页技术教程

go-zero快速开发单体服务和微服务

专职 2024-06-06 00:00:02
简介go-zero快速开发单体服务和微服务

环境准备

  • Go 1.15 及之前版本安装goctl

    GO111MODULE=on GOPROXY=https://goproxy.cn/,direct go get -u github.com/zeromicro/go-zero/tools/goctl@latest

  • Go 1.16 及以后版本安装goctl

    GOPROXY=https://goproxy.cn/,direct go install github.com/zeromicro/go-zero/tools/goctl@latest

  • 通过goctl安装protoc,protoc-gen-go,protoc-gen-grpc-go

    goctl env check -i -f

  • 直接创建api服务

    goctl api new greet

  • 通过api文件创建api服务

    goctl api go -api order.api -dir .

  • 通过proto文件创建rpc服务

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

创建greet单体服务

mkdir go-zero-demo
cd go-zero-demo
# 创建go.mod文件
go mod init go-zero-demo
# goctl创建api服务
goctl api new greet
# 更新相关依赖
go mod tidy

查看greet目录结构

$ tree greet
greet
├── etc
│   └── greet-api.yaml
├── greet.api
├── greet.go
└── internal
    ├── config
    │   └── config.go
    ├── handler
    │   ├── greethandler.go
    │   └── routes.go
    ├── logic
    │   └── greetlogic.go
    ├── svc
    │   └── servicecontext.go
    └── types
        └── types.go

接下来我们就可以在greetlogic.go中编写业务代码了。

编写逻辑

func (l *GreetLogic) Greet(req *types.Request) (*types.Response, error) {
    return &types.Response{
        Message: "Hello go-zero",
    }, nil
}

启动并访问服务

# 启动服务
$ cd greet
$ go run greet.go -f etc/greet-api.yaml

# 浏览器访问服务
http://localhost:8888/from/you

微服务

创建mall工程

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

创建user rpc服务

$ mkdir -p mall/user/rpc

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

$ vim mall/user/rpc/user.proto

增加如下代码:

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);
}

生成代码 如未安装 protoc,protoc-gen-go,protoc-gen-grpc-go 你可以通过如下指令一键安装

$ goctl env check -i -f

注意: 1、每一个 *.proto文件只允许有一个service error: only one service expected

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

填充业务逻辑

# $ 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
}

创建order api服务

创建order api 服务

# 回到 go-zero-demo/mall 目录
$ mkdir -p order/api && cd order/api

添加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)
}

生成order服务

$ goctl api go -api order.api -dir .
Done.

添加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
}

添加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

完善服务依赖

# vim internal/svc/servicecontext.go

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)),
	}
}

添加order演示逻辑

给getorderlogic添加业务逻辑

# vim internal/logic/getorderlogic.go

package logic

import (
	"context"
	"errors"
	"go-zero-micro/mall/user/rpc/types/user"

	"go-zero-micro/mall/order/api/internal/svc"
	"go-zero-micro/mall/order/api/internal/types"

	"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) (resp *types.OrderReplay, err error) {
	// todo: add your logic here and delete this line
	userRes, err := l.svcCtx.UserRpc.GetUser(l.ctx, &user.IdRequest{
		Id: "1",
	})
	if err != nil {
		return nil, err
	}
	if userRes.Name != "test" {
		return nil, errors.New("用户不存在")
	}

	resp = &types.OrderReplay{
		Id:   req.Id,
		Name: "订单名称",
	}
	return
}

启动服务并验证

  • 启动etcd

  • 下载依赖

    # 在go-zero-demo目录下
    go mod tidy
    
  • 启动user rpc

    # 在mall/user/rpc目录
    go run user.go -f etc/user.yaml
    
  • 启动order api

    # 在mall/order/api目录
    go run order.go -f etc/order.yaml
    
  • 浏览器访问order api

    http://127.0.0.1:8888/api/order/get/1
    

参考官方文档

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。