ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

go-zero实战demo(一)

2022-07-01 15:02:49  阅读:207  来源: 互联网

标签:string demo json zero api user go


前言

听说下一个项目 可能要用微服务开发,趁着项目的空档期,对于go微服务的框架进行了学习。目前go的微服务框架个人认为处于百家齐放的时代,可能这也是go的生态的一个特点吧,也曾简单用过go-miecro,gin+micro+gorm+mysql+redis 常见方案使用起来还是蛮顺手的,可惜该框架成了个人仓库,生成的依赖会出现引用错误,其他的都蛮ok的。对于go-zero的选择,其实参考此篇文章:https://zhuanlan.zhihu.com/p/488233067 , 再加团队沟通协商及个人私心(认为其可以成为趋势及给自己加分)。 所以选择的go 微服务框架为go-zero。

版本浅介

go:1.17.6

protoc:3.20.1

goctl:1.3.8

mysql:8.0.29

redis:7.0.0

consul:1.12

demo 介绍

实现简单的用户表 增查

使用consul 替换etcd

相关接口

/api/user/login    			登录
�/api/user/register			注册
�/api/user/listuser		       查询所有用户
�/api/user/userinfo			查询 某个用户详情

源码:https://github.com/zisefeizhu/go-zero-demo

参考:

go-zero作者

https://www.cnblogs.com/kevinwan/category/2002486.html

go-zero 入门级demo

https://juejin.cn/post/7036011410265997348

demo 注意点

常用命令

touch user.api
goctl api go -api ./user.api -dir .
goctl model mysql ddl -src user.sql -dir . -c
touch user.proto
goctl rpc protoc ./rpc/user.proto --go_out=./rpc/types --go-grpc_out=./rpc/types  --zrpc_out=./rpc

1、consul 替换etcd

参考文章:https://github.com/zeromicro/zero-contrib/tree/main/zrpc/registry/consul

微服务

rpc/etcd/user.yaml

# consul   替换etcd
Consul:
  Host: 127.0.0.1:8500 # consul endpoint
  Key: user.rpc # 注册到consul的服务名字
  Meta:
    Protocol: grpc
  Tag:
    - tag
    - rpc

rpc/internal/config/config.go

type Config struct {
	zrpc.RpcServerConf
	Mysql struct {
		DataSource string
	}
	// consul
	Consul     consul.Conf
	CacheRedis cache.CacheConf
	Salt       string
}

rpc/user.go

import (
	"github.com/zeromicro/zero-contrib/zrpc/registry/consul"
  
  
func main(){
...... 
err := consul.RegisterService(c.ListenOn, c.Consul)
	if err != nil {
		os.Exit(1)
	}
 
defer s.Stop()
api

api/etcd/user.yaml

UserRpc:
 Target: consul://127.0.0.1:8500/user.rpc?wait=14s
 NonBlock: true

api/internalconfig/config.go

type Config struct {
	rest.RestConf
	Auth struct {
		AccessSecret string
		AccessExpire int64
	}
	UserRpc zrpc.RpcClientConf
}

api/user.go

import (
  	_ "github.com/zeromicro/zero-contrib/zrpc/registry/consul"
)
2、api层的user.api 书写

参考文档:https://go-zero.dev/cn/docs/design/grammar/#type语法块

例:

type (
	// 用户登录
	LoginRequest {
		Mobile   string `json:"mobile"`
		Password string `json:"password"`
	}
	LoginResponse {
		AccessToken  string `json:"accessToken"`
		AccessExpire int64  `json:"accessExpire"`
	}
	// 用户登录

	// 用户注册
	RegisterRequest {
		Name     string `json:"name"`
		Gender   int64  `json:"gender"`
		Mobile   string `json:"mobile"`
		Password string `json:"password"`
	}
	RegisterResponse {
		Id     int64  `json:"id"`
		Name   string `json:"name"`
		Gender int64  `json:"gender"`
		Mobile string `json:"mobile"`
	}
	// 用户注册

	// 用户信息
	UserInfoResponse {
		Id     int64  `json:"id"`
		Name   string `json:"name"`
		Gender int64  `json:"gender"`
		Mobile string `json:"mobile"`
	}

	// 列出所有用户
	ListUserResponse {
		Id     int64  `json:"id"`
		Name   string `json:"name"`
		Gender int64  `json:"gender"`
		Mobile string `json:"mobile"`
	}

	// 用户信息
)

service User {
	@handler Login
	post /api/user/login(LoginRequest) returns (LoginResponse)
	
	@handler Register
	post /api/user/register(RegisterRequest) returns (RegisterResponse)
	
	@handler ListUser
	post /api/user/listuser returns (ListUserResponse)
}

@server(
	jwt: Auth
)
service User {
	@handler UserInfo
	post /api/user/userinfo returns (UserInfoResponse)
}
3、model层

go-zero不会根据sql自动创建表结构,但是可以根据表结构创建dao层

参考:https://go-zero.dev/cn/docs/advance/model-gen

通常只会生成:Insert / FindOne / FindOneByxxx/Update/Delete 方法,其他方法需要自己填充

例:
rpc/model/usermpdel_gen.go

添加FindList方法

userModel interface {
		Insert(ctx context.Context, data *User) (sql.Result, error)
		FindOne(ctx context.Context, id int64) (*User, error)
		FindOneByMobile(ctx context.Context, mobile string) (*User, error)
		FindList() ([]*User, error)  // 新增
		Update(ctx context.Context, newData *User) error
		Delete(ctx context.Context, id int64) error
	}
  
  // 实现
 func (m *defaultUserModel) FindList() ([]*User, error) {
	var resp []*User
	query := fmt.Sprintf("select %s from %s ", userRows, m.table)
	err := m.QueryRowsNoCache(&resp, query)
	switch err {
	case nil:
		return resp, nil
	case sqlc.ErrNotFound:
		return nil, ErrNotFound
	default:
		return nil, err
	}
}

参考:https://talkgo.org/t/topic/1461

4、rpc 业务逻辑实现

rpc 层重点关注rpc/internal/logic 目录,内是业务的真正实现

以查所有用户为例

func (l *ListUserLogic) ListUser(in *user.ListUserRequest) (*user.ListUserResponse, error) {
	results, err := l.svcCtx.UserModel.FindList()
	if err != nil {
		if err == model.ErrNotFound {
			return nil, status.Error(100, "用户不存在")
		}
		return nil, status.Error(500, err.Error())
	}
	resp := make([]*user.UserInfoResponse, 0, len(results))

	for _, item := range results {
		resp = append(resp, &user.UserInfoResponse{
			Id:     item.Id,
			Name:   item.Name,
			Gender: item.Gender,
			Mobile: item.Mobile,
		})
	}
	return &user.ListUserResponse{
		Data: resp,
	}, nil
}
5、go-zero的proto 书写

在proto中如果func 没有参数,不能:grpc-go protobuf Empty ,而是定位为空message

参考:https://github.com/zeromicro/go-zero/issues/825

6、对于go-zero的还需改造点

1、配置文件读取环境变量

2、设置context的超时时间

3、将go-zero里的rpc和api分别build成可执行程序

4、等

总结

总的来说go-zero使用起来有一些束缚 ,不如micro 灵活随意。不可否认的是go-zero封装的相对更好,使开发者基本只用关注业务逻辑。
在业务全面容器化及以istio为主的服务治理越来越主流的当下及未来:个人觉得在代码层面实现服务治理能力似乎不能算是一种优势。其实在以kubernetes 为标准的容器深度发展的当下,客人认为开发者应该回到重点关注业务的实现逻辑,而治理应下移到基础设施层,即Kubernetes + 业务 + 服务治理(istio) 。

标签:string,demo,json,zero,api,user,go
来源: https://www.cnblogs.com/zisefeizhu/p/16434695.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有