go-zero学习笔记(六)---gozero中间件介绍

​ 1. 中间件分类

复制代码
    gozero默认中间件
    通过在api文件中创建的中间件
    通过server.Use(middleware Middleware)创建的中间件

2. 中间件介绍

2.1 gozero默认中间件

复制代码
    默认中间件包括如下:

在gozero中对应的代码为:

go 复制代码
// 文件位置:github.com\zeromicro\go-zero@v1.7.6\rest\engine.go
func (ng *engine) buildChainWithNativeMiddlewares(fr featuredRoutes, route Route,
	metrics *stat.Metrics) chain.Chain {
	chn := chain.New()

	if ng.conf.Middlewares.Trace {
		chn = chn.Append(handler.TraceHandler(ng.conf.Name,
			route.Path,
			handler.WithTraceIgnorePaths(ng.conf.TraceIgnorePaths)))
	}
	if ng.conf.Middlewares.Log {
		chn = chn.Append(ng.getLogHandler())
	}
	if ng.conf.Middlewares.Prometheus {
		chn = chn.Append(handler.PrometheusHandler(route.Path, route.Method))
	}
	if ng.conf.Middlewares.MaxConns {
		chn = chn.Append(handler.MaxConnsHandler(ng.conf.MaxConns))
	}
	if ng.conf.Middlewares.Breaker {
		chn = chn.Append(handler.BreakerHandler(route.Method, route.Path, metrics))
	}
	if ng.conf.Middlewares.Shedding {
		chn = chn.Append(handler.SheddingHandler(ng.getShedder(fr.priority), metrics))
	}
	if ng.conf.Middlewares.Timeout {
		chn = chn.Append(handler.TimeoutHandler(ng.checkedTimeout(fr.timeout)))
	}
	if ng.conf.Middlewares.Recover {
		chn = chn.Append(handler.RecoverHandler)
	}
	if ng.conf.Middlewares.Metrics {
		chn = chn.Append(handler.MetricHandler(metrics))
	}
	if ng.conf.Middlewares.MaxBytes {
		chn = chn.Append(handler.MaxBytesHandler(ng.checkedMaxBytes(fr.maxBytes)))
	}
	if ng.conf.Middlewares.Gunzip {
		chn = chn.Append(handler.GunzipHandler)
	}

	return chn
}

没有jwt.auth的?

搁着了,哈哈

go 复制代码
// github.com\zeromicro\go-zero@v1.7.6\rest\engine.go
// 注意这段代码,一会还要用!!!
func (ng *engine) bindRoute(fr featuredRoutes, router httpx.Router, metrics *stat.Metrics,
	route Route, verifier func(chain.Chain) chain.Chain) error {
	chn := ng.chain
	if chn == nil {
		chn = ng.buildChainWithNativeMiddlewares(fr, route, metrics)
	}

	chn = ng.appendAuthHandler(fr, chn, verifier) //搁着了,哈哈

	for _, middleware := range ng.middlewares {
		chn = chn.Append(convertMiddleware(middleware))
	}
	handle := chn.ThenFunc(route.Handler)

	return router.Handle(route.Method, route.Path, handle)
}

2.2 通过在api文件中创建的中间件

在制作api文件时,可以通过如下代码生成中间件

go 复制代码
@server(
	middleware: checkMiddleware, testMiddleware  // 中间件, 多个中间件用逗号分割
)

最终生成的中间件位于

go 复制代码
// api/internal/handler/routes.go
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
	server.AddRoutes(
		rest.WithMiddlewares(
			[]rest.Middleware{serverCtx.CheckMiddleware, serverCtx.TestMiddleware},
			[]rest.Route{
				{
					Method:  http.MethodPost,
					Path:    "/Info/get",
					Handler: demo.GetInfoHandler(serverCtx),
				},
			}...,
		),
		rest.WithPrefix("/api/demo/v1"),
	)
}

根据代码可以判断出,该方式生成的中间件与路径绑定,并一起注册到server中。

2.3 通过server.Use(middleware Middleware)创建的中间件

我们还可以通过调用server.Use(middleware Middleware)函数创建中间件:

go 复制代码
	server := rest.MustNewServer(c.RestConf)
	defer server.Stop()

	ctx := svc.NewServiceContext(c)
	handler.RegisterHandlers(server, ctx)

	server.Use(ctx.CheckMiddleware) 
	// 多个可多次调用,最终是append到list的

具体函数信息:

go 复制代码
	// github.com\zeromicro\go-zero@v1.7.6\rest\server.go
	// Use adds the given middleware in the Server.
	func (s *Server) Use(middleware Middleware) {
		s.ngin.use(middleware)
	}

	func (ng *engine) use(middleware Middleware) {
		ng.middlewares = append(ng.middlewares, middleware)
	}

3. 中间件的执行顺序

通过​上述介绍,我们可以发现,gozero存在三种中间件(个人理解),那么这三种中间件的执行顺序是咋样的呢,哪个先执行,哪个后执行?

**答案:**先是默认中间件,再是use的中间件,最后是api生成的中间件。当然,各部分内部执行顺序遵循中间件执行顺序。

原理:

go 复制代码
// github.com\zeromicro\go-zero@v1.7.6\rest\engine.go
func (ng *engine) bindRoute(fr featuredRoutes, router httpx.Router, metrics *stat.Metrics,
	route Route, verifier func(chain.Chain) chain.Chain) error {
	chn := ng.chain
	if chn == nil {
		chn = ng.buildChainWithNativeMiddlewares(fr, route, metrics) // 默认中间件加载
	}

	chn = ng.appendAuthHandler(fr, chn, verifier) // 认证中间件

	for _, middleware := range ng.middlewares {
		chn = chn.Append(convertMiddleware(middleware)) // use中间件加载
	}
	handle := chn.ThenFunc(route.Handler) // route中间件加载

	return router.Handle(route.Method, route.Path, handle)
}

总体流程:

go 复制代码
server.Start()---> 
start() ---> 
bindRoutes() ---> 
bindFeaturedRoutes() ---> 
bindRoute()

4. 默认中间件关闭

查看gozero默认配置项,如下:

go 复制代码
	MiddlewaresConf struct {
		Trace      bool `json:",default=true"`
		Log        bool `json:",default=true"`
		Prometheus bool `json:",default=true"`
		MaxConns   bool `json:",default=true"`
		Breaker    bool `json:",default=true"`
		Shedding   bool `json:",default=true"`
		Timeout    bool `json:",default=true"`
		Recover    bool `json:",default=true"`
		Metrics    bool `json:",default=true"`
		MaxBytes   bool `json:",default=true"`
		Gunzip     bool `json:",default=true"`
	}

	RestConf struct {
		service.ServiceConf
		Host     string `json:",default=0.0.0.0"`
		Port     int
		CertFile string `json:",optional"`
		KeyFile  string `json:",optional"`
		Verbose  bool   `json:",optional"`
		MaxConns int    `json:",default=10000"`
		MaxBytes int64  `json:",default=1048576"`
		// milliseconds
		Timeout      int64         `json:",default=3000"`
		CpuThreshold int64         `json:",default=900,range=[0:1000)"`
		Signature    SignatureConf `json:",optional"`
		// There are default values for all the items in Middlewares.
		Middlewares MiddlewaresConf
		// TraceIgnorePaths is paths blacklist for trace middleware.
		TraceIgnorePaths []string `json:",optional"`
	}

因此,要关闭某一默认中间件,直接在配置文件中设置false就可以了。

yaml 复制代码
# 例如:
Name: demo-api
Host: 0.0.0.0
Port: 8888
Middlewares:
  Prometheus: false
  
相关推荐
暴风游侠16 分钟前
linux知识点-内核参数相关
linux·运维·服务器·笔记
源代码•宸4 小时前
分布式缓存-GO(分布式算法之一致性哈希、缓存对外服务化)
开发语言·经验分享·分布式·后端·算法·缓存·golang
Galloping-Vijay5 小时前
Claude Code 使用笔记
笔记
旖旎夜光5 小时前
多态(11)(下)
c++·学习
极市平台6 小时前
骁龙大赛-技术分享第5期(上)
人工智能·经验分享·笔记·后端·个人开发
全栈陈序员6 小时前
【Python】基础语法入门(十七)——文件操作与数据持久化:安全读写本地数据
开发语言·人工智能·python·学习
啄缘之间6 小时前
11. UVM Test [uvm_test]
经验分享·笔记·学习·uvm·总结
RisunJan7 小时前
【行测】类比推理-自称他称全同
学习
wan55cn@126.com7 小时前
人类文明可通过技术手段(如加强航天器防护、改进电网设计)缓解地球两极反转带来的影响
人工智能·笔记·搜索引擎·百度·微信
石像鬼₧魂石7 小时前
Termux ↔ Windows 靶机 反向连接实操命令清单
linux·windows·学习