go-zero 的使用

目录

[1. 生成 user api 服务](#1. 生成 user api 服务)

[2. 生成 user rpc 服务](#2. 生成 user rpc 服务)

[3. 生成 user model 模型](#3. 生成 user model 模型)

[4. 编写 user rpc 服务](#4. 编写 user rpc 服务)

[1 修改配置文件 user.yaml](#1 修改配置文件 user.yaml)

[2 添加 user model 依赖](#2 添加 user model 依赖)

[3 添加用户登录逻辑 Login](#3 添加用户登录逻辑 Login)

[5. 编写 user api 服务](#5. 编写 user api 服务)

[1 修改配置文件user.yaml](#1 修改配置文件user.yaml)

[2 添加 user rpc 依赖](#2 添加 user rpc 依赖)

[3 添加用户登录逻辑 Login](#3 添加用户登录逻辑 Login)

[6. 启动服务](#6. 启动服务)

启动rpc服务

启动api服务


本文章讲解使用go-zero生成一个微服务的过程。其中的一些命令或者名不太熟悉的话,可以参考go-zero官网。

项目名字叫zero。创建zero目录,并在该目录下创建user目录。

1. 生成 user api 服务

在user目录下添加api目录,在api目录添加如下的api文件。

bash 复制代码
syntax = "v1"

type LoginReq {
	UserName string `json:"username"`
	Password string `json:"password"`
}

type LoginResponse {
	Token string `json:"token"`
}

@server (
	prefix: v1
)
service user {
	@handler login
	post /user/login (LoginReq) returns (LoginResponse)
}

在user/api下执行

bash 复制代码
goctl go api --api ./user.api --dir .

执行生成后,api目录结构体如下

bash 复制代码
.
├── etc
│   └── user.yaml
├── internal
│   ├── config
│   │   └── config.go
│   ├── handler
│   │   ├── loginhandler.go
│   │   └── routes.go
│   ├── logic
│   │   └── loginlogic.go
│   ├── svc
│   │   └── servicecontext.go
│   └── types
│       └── types.go
├── user.api
└── user.go

2. 生成 user rpc 服务

在user目录下创建rpc目录。在rpc目录下添加如下的proto文件。

bash 复制代码
syntax="proto3";

package user;

option go_package="./user";

//用户登录

message LoginRequest{
    string username=1;
    string Password=2;
}

message LoginResponse{
    int64 Id=1;
    string Username=2;
}

service User{
    rpc Login(LoginRequest)returns(LoginResponse);
}

在user/rpc下执行

bash 复制代码
goctl rpc protoc ./user.proto --go_out=. --go-grpc_out=. --zrpc_out=.

执行生成后,rpc目录结构如下

bash 复制代码
.
├── etc
│   └── user.yaml
├── internal
│   ├── code
│   │   └── code.go
│   ├── config
│   │   └── config.go
│   ├── db
│   │   └── mysql.go
│   ├── logic
│   │   └── loginlogic.go
│   ├── server
│   │   └── userserver.go
│   └── svc
│       └── servicecontext.go
├── user
│   ├── user_grpc.pb.go
│   └── user.pb.go
├── userclient
│   └── user.go
├── user.go
└── user.proto

3. 生成 user model 模型

在user目录添加model目录,在model中添加如下的user.sql文件。

bash 复制代码
 CREATE TABLE `user` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=26;

在model目录中执行

bash 复制代码
goctl model mysql ddl --src user.sql --dir .

执行生成后,model目录结构体如下

bash 复制代码
.
├── usermodel_gen.go
├── usermodel.go
├── user.sql
└── vars.go

4. 编写 user rpc 服务

1 修改配置文件 user.yaml

因为需要使用数据库MySql,所以我们需要配置数据库的参数,所以需要在user.yaml中填写数据库相关的参数 。而因为rpc是需要用到Etcd(用于服务注册发现等),所以还需要添加Etcd的配置

bash 复制代码
Name: user.rpc
ListenOn: 0.0.0.0:8080

#Etcd部分和Mysql部分是新添加的
Etcd:
  Hosts:
  - 127.0.0.1:2379
  Key: user.rpc

Mysql:
  datasource: "root:wook1847@tcp(127.0.0.1:3306)/zero?charset=utf8mb4&parseTime=True&loc=Local"

2 添加 user model 依赖

  • 添加 Mysql 服务配置的实例化

在生成的config目录中有config.go文件,该文件中是用于解析配置文件的结构体。而这里我们添加了MySql配置,所以需要添加相关结构体来进行解析。而rest.RestConf中就带有etcd的(看源码),所以不用写etcd的。

Go 复制代码
type Config struct {
	zrpc.RpcServerConf

	MysqlConfig Mysql `json:"mysql"`    //添加mysql的配置
}

type Mysql struct {
	Datasource    string
	ConectTimeout int64
}
  • 注册服务上下文 user model 的依赖

在生成是svc目录中的 servicecontext.go文件,后续我们就是使用该文件中的ServiceContext。而要想可以使用mysql,那就需要在其添加该依赖。

bash 复制代码
type ServiceContext struct {
	Config config.Config
	Conn   sqlx.SqlConn    //这个就是新添加的依赖
}

func NewServiceContext(c config.Config) *ServiceContext {
	conn := sqlx.NewMysql(c.MysqlConfig.Datasource)
	return &ServiceContext{
		Config: c,
		Conn:   conn,
	}
}

3 添加用户登录逻辑 Login

接着看生成的logic目录中的loginlogic.go文件。这里就是我们要写的业务逻辑地方。logic目录中的文件是我们主要写代码的地方。在Login方法中添加业务逻辑。

Go 复制代码
type LoginLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic {
	return &LoginLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *LoginLogic) Login(in *user.LoginRequest) (*user.LogResponse, error) {
	// todo: add your logic here and delete this line
	res, err := model.NewUserModel(l.svcCtx.Conn).FindOneByNameAndPwd(l.ctx, in.Username, in.Password)
	if err != nil {
		fmt.Println("login rpc err.........................:", err)
		if err == model.ErrNotFound {
			return nil, err
		}
		return nil, err
	}

	return &user.LogResponse{Id: res.Id, Username: res.Username}, nil
}

5. 编写 user api 服务

其过程和编写user rpc服务是类似的。

1 修改配置文件user.yaml

因为我们在api中需要使用rpc,所以我们就需要用到etcd,所以就需要etcd的配置。

bash 复制代码
Name: user
Host: 0.0.0.0
Port: 8888


#添加user rpc的etcd配置
UserRpc:
  Etcd:
    Hosts:
    - 127.0.0.1:2379
    Key: user.rpc


#要是还需要其他服务的rpc,那就需要添加的
# PayRpc:
#   Etcd:
#     Hosts:
#     - 127.0.0.1:2379
#     Key: pay.rpc

2 添加 user rpc 依赖

  • 添加 user rpc 服务配置的实例化

在user.yaml中添加了user rpc的etcd配置后,那就需要再config.go文件中添加对应的结构体来解析配置。

而前面不是说了,etcd的结构体是rest.RestConf就带有的,不用填写了吗?

这不是这个意思的。这个是对应user rpc的etcd配置的。要是在api中还需要用其他服务,比如支付服务,而支付服务又是一个微服务,那就又要添加pay rpc的etcd配置的。

Go 复制代码
type Config struct {
	rest.RestConf
	UserRpc zrpc.RpcClientConf

	// PayRpc zrpc.RpcClientConf	要是需要该服务的话,就需要添加
}
  • 添加 user rpc 服务配置的实例化
bash 复制代码
type ServiceContext struct {
	Config config.Config

	UserRpc userclient.User    //添加user rpc使用
}

func NewServiceContext(c config.Config) *ServiceContext {
	return &ServiceContext{
		Config:  c,
		UserRpc: userclient.NewUser(zrpc.MustNewClient(c.UserRpc)),
	}
}

3 添加用户登录逻辑 Login

在生成的logic目录中的loginlogic.文件。这里就是我们要写的业务逻辑。

Go 复制代码
type LoginLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic {
	return &LoginLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

//在该方法中添加我们的业务逻辑
func (l *LoginLogic) Login(req *types.LoginReq) (resp *types.LoginResponse, err error) {
	// todo: add your logic here and delete this line

	_, err = l.svcCtx.UserRpc.Login(l.ctx, &userclient.LoginRequest{
		Username: req.UserName,
		Password: req.Password,
	})

	if err != nil {
		return nil, err
	}

	return &types.LoginResponse{Token: "123445"}, nil
}

6. 启动服务

因为api服务是依赖rpc服务,所以先启动rpc服务,再启动api服务。

启动rpc服务

在user/api中执行

bash 复制代码
go run user.go

启动api服务

在user/rpc中执行

bash 复制代码
go run user.go
相关推荐
LUCIAZZZ7 小时前
TCP基本入门-简单认识一下什么是TCP
java·网络·后端·网络协议·tcp/ip·计算机网络·spring
_未知_开摆7 小时前
2020年蓝桥杯Java B组第二场题目+部分个人解析
java·经验分享·后端·程序人生·蓝桥杯
m0_748234527 小时前
Spring Boot整合WebSocket
spring boot·后端·websocket
m0_748232398 小时前
SpringBoot Maven 项目 pom 中的 plugin 插件用法整理
spring boot·后端·maven
Asthenia04128 小时前
深入解析消息持久化实现机制:基于 `LocalMqBrokerPersist` 的简化实现
后端
yuhaiqiang9 小时前
解密如何快速搭建一套虚拟商品交易系统,推荐这个神奇的开源项目
后端
xidianhuihui9 小时前
go如何排查某个依赖是哪里引入的
开发语言·后端·golang
怡~9 小时前
Golang适配达梦数据库连接指定模式
开发语言·数据库·golang
姜来可期9 小时前
【Golang】go语言异常处理快速学习
开发语言·笔记·后端·学习·golang
m0_548049709 小时前
QNAP威联通NAS第三方动态域名解析之docker部署DDNS GO
docker·eureka·golang