乐趣区

关于go:Go框架gin框架是如何做崩溃处理的

大家好,我是 渔夫子

本文咱们介绍下 recover 在 gin 框架中的利用。
首先,在 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 框架也有同样的机制,实现原理也是一样的。

公众号:Go 学堂

特地阐明:你的关注,是我写下去的最大能源。点击下方公众号卡片,间接关注。关注送《100 个 go 常见的谬误》pdf 文档、经典 go 学习材料。

退出移动版