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