本文介绍: 在gin中,是通过使用中间件捕获panic,并保证服务down机的。在defer函数中,如果捕获panic,则将panic详细详细记录下来,可以发送指定输出中,即函数指定out参数默认os.Stderr),也可以指定其他的文件或Sentry等。当然,这在生产环境下是不可接受的。首先,在golang中,如果在子协程遇到panic,那么主协程也会被终止。在gin中,正是该中间件应用,确保了web服务的健壮性。当然,其他的web框架也有同样的机制实现原理也是一样的。

本文我们介绍recovergin框架中的应用。 首先,在golang中,如果在子协程遇到panic,那么主协程也会被终止如下

package main

import (
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()

    // 在子协程中引起panic,主协程也会退出
	go func() {
		panic("hello world")
	}()
    
	// Listen and Server in 0.0.0.0:8080
	r.Run(":8080")
}

panic描述不可处理错误。在web服务就是服务会崩溃。当然,这在生产环境下是不可接受的。那么,如何能够做到发生panic技能捕获该panic又能让服务继续健康运行呢?
就是golang中提供的recover函数了。recover函数能够捕获Panic错误并恢复程序的正常运行
接下来我们看下recover函数在gin框架中是如何应用的。
首先,要提到的就是gin框架中的recovery中间件。在gin中,是通过使用中间件捕获panic,并保证服务不down机的。 如果使用gin.Default()函数进行构建gin对象,那么默认注册了Recovery中间件

func Default() *Engine {
	debugPrintWARNINGDefault()
	engine := New()
    //  注册了Recovery中间件
	engine.Use(Logger(), Recovery())
	return engine
}

其次,我们来看下Recovery()中间件都做了些什么

Recovery()函数定义如下

func Recovery() HandlerFunc {
	return RecoveryWithWriter(DefaultErrorWriter)
}

这里的DefaultErrorWriter默认的输出端,即os.Stderr。即指错误的输出到什么地方。

接下来看RecoveryWithWriter函数中的实现

// RecoveryWithWriter returns a middleware for a given writer that recovers from any panics and writes a 500 if there was one.
func RecoveryWithWriter(out io.Writer, recovery ...RecoveryFunc) HandlerFunc {
	if len(recovery) > 0 {
		return CustomRecoveryWithWriter(out, recovery[0])
	}
	return CustomRecoveryWithWriter(out, defaultHandleRecovery)
}

这里一个参数defaultHandleRecovery我们看下它的实现

func defaultHandleRecovery(c *Context, err any) {
	c.AbortWithStatus(http.StatusInternalServerError)
}

就是写入一个代表内部服务器错误的状态码500,并结束了本次请求

这里关键点是CustomRecoveryWithWriter的实现代码很长,我们分段来看。如下
在这里插入图片描述
主要分三部分

日志输出到out中,这里上述提到的DefaultErrorWriter,即os.Stderr
defer延迟执行部分。
c.Next()正常请求处理器部分。

这里需要注意的点就是

recover函数需要defer调用。因为defer是在函数返回时才调用,所以当发生panic时会导致函数返回,这样才能捕获panic。
作为中间件运行,说明每次请求处理器都被中间件包装了,也就相当于每个请求处理器都有这个defer函数。
defer数中,如果捕获了panic,则将panic的详细详细记录下来,可以发送指定的输出中,即函数中指定的out参数默认os.Stderr),也可以指定其他的文件或Sentry等。

在gin中,正是该中间件的应用,确保了web服务的健壮性。当然,其他的web框架也有同样的机制实现原理也是一样的。

原文地址:https://blog.csdn.net/ldxxxxll/article/details/134781315

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_43004.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注