• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

go-zero学习 Mikaelemmmm的视频

武飞扬头像
西木Qi
帮助1

go-zero系列视频教程【Mikaelemmmm】整理,后面章节需要结合go-zero-looklook的代码。Mikaelemmmmgithub上还有别的好的代码示例可以研究下。

提示

注意:标※的章节个人认为是比较重要,需要了解的。

※一、go-zero简介及如何学go-zero

1、zero-gorm:https://github.com/yfanswer/zero-gorm
2、公众号:微服务实践
3、go-zero-example:
4、zero-conttrib:
5、微信社区群:
6、go-zero-issue:

二、go-zero环境搭建

三、go-zero杀手锏goctl详细使用

五、api服务之api文件

六、api服务之代码讲解

七、api服务数据库操作

八、gotctl小于1.3.3生成model一个小bug

※九、sqlc执行源码分析与model详解

sqlx切换成gorm的流程:
1、sqlx 切成gorm,同时结合sqlc;这种骚操作怎么改的,看到网上有同学这样干。
2、只需要把带缓存生成的model中,sqlx执行db部分换成gorm即可。
3、替换后不影响go-zero 中封装的数据库分布式事务,因为dtm支持gorm,可以看dtm官网。

Cache缓存的使用:
sqlc中包含sqlx。
Cache缓存其实用的就是Redis,可以使用同一个Redis,也可以分开。
Cache缓存的使用实际是为了处理Redis缓存击穿,这块的代码很有借鉴意义。

※十、go-zero本地事务以及源码分析【待整理】

事务需要自己手动实现,特别是主子表同时插入的情况。

※十一、api服务之middleware

在中间件中处理数据时,不论是操作Redis、数据库,还是其他RPC,需要什么,在创建中间件时就New对应的环境即可。
全局中间件、局部中间件的使用顺序:
全局中间件→局部中间件1→局部中间件2→全局中间件

※十二、go-zero的Log

Mode:可以同时设置console、file,即同时输出到日志文件和控制台。
StackCooldownMillis:是设置stat日志统计输出间隔,表示间隔多久,打印出慢日志,比如运行了200ms,还没出结果,就打印慢查询,默认100。

zero-example中有文件上传的例子。

※十三、go-zero单体项目及配置如何查看

超时时间Timeout的配置位置。

※十四、go-zero的api整体源码分析【待整理】

1、启动类里各个配置的启动过程
2、golang的可变参数
3、threading.GoSafe(),go-zero封装的安全的协程创建,threading包有一些好用的方法值得研究借鉴。

十五、go-zero的rpc服务简单介绍

※十六、rpc服务如何独立调试

使用postman测试go-zero的grpc服务时,必须在配置文件中加入Mode: dev,然后重启服务。
详见:编写简单的逻辑代码

十七、api如何调用rpc

十八、go-zero中写protobuf注意点

十九、sql2pb告别手写pb的烦恼

Mikaelemmmm自己封装了根据数据表生成.pb.go文件的工具,减少开发时间。

二十、rpc中如何使用model

※二十一、api与rpc通过etcd服务发现

1、go-zero使用k8s时,服务发现不能使用直连方式,可能会导致负载不均衡。
2、api服务的yaml中ListenOn: 0.0.0.0:8080,和rpc服务的yaml中Host: 0.0.0.0,设置成0.0.0.0的话会自动获取内网IP,如果设置成固定内网ip的话就是直接写死了。

※二十二、api与rpc直连方式服务发现

在api服务的yaml中将Etcd的配置删除,加上Endpoints即可。

※二十三、api与rpc使用k8s服务发现及部署【待整理】

1、有朋友说,基于k8s 服务发现 gin grpc直接使用k8s默认负载均衡也可以,默认grpc在k8s中会导致负载不均衡,go-zero不是使用的默认k8s负载均衡方式(如果你用了直链协议就走了默认了,所以视频中我不推荐用直链,会导致负载不均衡) , 导致这种负载不均衡的原因是grpc底层http2的实现以及k8s的负载均衡有关系,如果默认使用直链方式也就是交给k8s自己去处理负载均衡,在http1.x短连接是没有问题的,grpc是使用http2实现的,它是长链接多路复用,后续发送的请求也都会打到相同pod,造成负载不均衡,所以go-zero内部已经自己实现了基于k8s的grpc负载均衡,拿到不同pod,把请求使用p2c方式分发到不同的pod,这样就均衡了,所以要使用go-zerok8s的协议,不能用直连协议,如果还不明白为什么默认grpc在k8s会负载不均衡可以谷歌。【来自Up主本人评论】

※二十四、rpc的服务端拦截器

在rpc服务端的启动类里加 s.AddUnaryInterceptors(),里面的参数是具体的拦截器,需要注意的是可以重复声明多个不同功能的拦截器。

func main() {
	flag.Parse()

	var c config.Config
	conf.MustLoad(*configFile, &c)
	ctx := svc.NewServiceContext(c)

	s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
		ucenter.RegisterUcenterSqlxServer(grpcServer, ucentersqlxServer.NewUcenterSqlxServer(ctx))
		ucenter.RegisterUcenterGormServer(grpcServer, ucentergormServer.NewUcenterGormServer(ctx))

		if c.Mode == service.DevMode || c.Mode == service.TestMode {
			reflection.Register(grpcServer)
		}
	})

	//s.AddUnaryInterceptors(func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
	//})

	s.AddUnaryInterceptors(TestServerInterceptor)

	//调整RPC收到的消息体大小限制
	s.AddOptions(grpc.MaxRecvMsgSize(1024 * 1024 * 1024)) // 1024 MB
	//s.AddOptions(grpc.MaxSendMsgSize(1024 * 1024 * 1024)) // 1024 MB
	defer s.Stop()

	fmt.Printf("Starting rpc server at %s...\n", c.ListenOn)
	s.Start()
}

// TestServerInterceptor 全局拦截器
func TestServerInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
	fmt.Printf("TestServerInterceptor ====> Start \n")
	fmt.Printf("req ====> % v \n", req)
	fmt.Printf("info ====> % v \n", info)
	resp, err = handler(ctx, req)

	fmt.Printf("TestServerInterceptor ====> End \n")
	return resp, err
}

※二十五、rpc的客户端拦截器

rpc的客户端拦截器也就是go-zero的api服务端。

package svc

import (
	"context"
	"fmt"
	"github.com/zeromicro/go-zero/rest"
	"github.com/zeromicro/go-zero/zrpc"
	"go-zero-micro/api/code/ucenterapi/internal/config"
	"go-zero-micro/api/code/ucenterapi/internal/middleware"
	"go-zero-micro/rpc/code/ucenter/client/ucentergorm"
	"go-zero-micro/rpc/code/ucenter/client/ucentersqlx"
	"谷歌.golang.org/grpc"
)

type ServiceContext struct {
	Config         config.Config
	Check          rest.Middleware
	UcenterGormRpc ucentergorm.UcenterGorm //gorm方式的接口
	UcenterSqlxRpc ucentersqlx.UcenterSqlx //sqlx方式的接口
}

func NewServiceContext(c config.Config) *ServiceContext {
	return &ServiceContext{
		Config:         c,
		Check:          middleware.NewCheckMiddleware().Handle,
		UcenterGormRpc: ucentergorm.NewUcenterGorm(zrpc.MustNewClient(c.UCenterRpc)),
		UcenterSqlxRpc: ucentersqlx.NewUcenterSqlx(zrpc.MustNewClient(c.UCenterRpc, zrpc.WithUnaryClientInterceptor(RpcClientInterceptor))),
	}
}

// RpcClientInterceptor rpc的客户端拦截器
func RpcClientInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
	fmt.Printf("RpcClientInterceptor ====> Start \n")
	fmt.Printf("req ====> % v \n", req)

	err := invoker(ctx, method, req, reply, cc, opts...)
	fmt.Printf("RpcClientInterceptor ====> End \n")
	if err != nil {
		return err
	}
	return nil
}

※二十六、不同服务之间通过metadata传值

  1. rpc的客户端拦截器
func interceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
	md := metadata.New(map[string]string{"x": "xx"})
	ctx = metadata.NewOutgoingContext(ctx, md)
	//logx.Debug("调用rpc服务前")
	err := invoker(ctx, method, req, reply, cc)
	if err != nil {
		return err
	}
	//logx.Debug("调用rpc服务后")
	return nil
}
  1. rpc的服务端接收
    在具体的xxxlogic.go代码逻辑中使用
	if md, ok := metadata.FromIncomingContext(l.ctx); ok {
		tmp := md.Get("user_id")
		if len(tmp) > 0 {
			uid, _ := strconv.ParseInt(tmp[0], 10, 64)
			fmt.Printf("userId:%d", uid)
		}
	}

※二十七、go-zero rpc启动源码流程分析【待整理】

gorm:https://github.com/SpectatorNan/gorm-zero

※二十八、go-zero的rpc-client发现rpc-server源码分析【待整理】

二十九、go-zero单体项目最佳实践

需要注意的是:api文件中多个service定义的名称必须要一致。例如:

@server(
	group: ucenter
	prefix: /ucenter
)
service ucenter-api {
	@doc(
		summary: "1 校验账号是否已存在"
	)
	@handler getUserByAccount
	get /getUserByAccount (UserSimpleModel) returns (BaseModel)
}

@server(
	group: login
	prefix: /login
)
service ucenter-api {
	@doc(
		summary: "9 用户账号密码登录"
	)
	@handler loginByPassword
	post /loginByPassword (UserLoginPasswordModel) returns (UserLoginResp)
}

三十、go-zero的api参数校验集成第三方库

※三十一、goctl的template定制化自己的需求

使用模板可以减少重复编写代码的,如model里的,api、rpc等。

※三十二、32 go-zero-looklook业务架构

1、链路追踪 我最新发的文章在go-zero公众号有,包括跟mq 打通的,熔断降级公众号也有。分布式事务可以看go-zero-looklook的文档中有一节专门讲go-zero对接dtm的,源码级别讲解,如果可以顺便给go-zero-looklook一个star支持【Up主本人评论】

2、asynq,基于redis的定时任务。

※三十三、go-zero-looklook开发教程

视频讲解内容,建议先看一下代码,提前了解一下代码和项目,最好是跟着代码自己亲自实践一遍,加深理解及掌握使用。

  1. 项目架构图讲解
  2. docker-compose.yml
  3. 开发环境搭建.md【文档讲解】
  4. asnq【定时任务】的源码及使用示例

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgekkhk
系列文章
更多 icon
同类精品
更多 icon
继续加载