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
  
相关推荐
汇能感知9 小时前
摄像头模块在运动相机中的特殊应用
经验分享·笔记·科技
阿巴Jun10 小时前
【数学】线性代数知识点总结
笔记·线性代数·矩阵
茯苓gao10 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾10 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
DKPT11 小时前
Java内存区域与内存溢出
java·开发语言·jvm·笔记·学习
aaaweiaaaaaa11 小时前
HTML和CSS学习
前端·css·学习·html
ST.J11 小时前
前端笔记2025
前端·javascript·css·vue.js·笔记
Suckerbin11 小时前
LAMPSecurity: CTF5靶场渗透
笔记·安全·web安全·网络安全
看海天一色听风起雨落12 小时前
Python学习之装饰器
开发语言·python·学习
小憩-12 小时前
【机器学习】吴恩达机器学习笔记
人工智能·笔记·机器学习