Recover 是一个Go语言的内建函数,可以让进入宕机流程中的 goroutine 恢复过来,recover 仅在延迟函数 defer 中有效,在正常的执行过程中,调用 recover 会返回 nil 并且没有其他任何效果,如果当前的 goroutine 陷入恐慌,调用 recover 可以捕获到 panic 的输入值,并且恢复正常的执行。
晋中网站建设公司成都创新互联,晋中网站设计制作,有大型网站制作公司丰富经验。已为晋中成百上千提供企业网站建设服务。企业网站搭建\外贸网站制作要多少钱,请找那个售后服务好的晋中做网站的公司定做!
通常来说,不应该对进入 panic 宕机的程序做任何处理,但有时,需要我们可以从宕机中恢复,至少我们可以在程序崩溃前,做一些操作,举个例子,当 web 服务器遇到不可预料的严重问题时,在崩溃前应该将所有的连接关闭,如果不做任何处理,会使得客户端一直处于等待状态,如果 web 服务器还在开发阶段,服务器甚至可以将异常信息反馈到客户端,帮助调试。
在其他语言里,宕机往往以异常的形式存在,底层抛出异常,上层逻辑通过 try/catch 机制捕获异常,没有被捕获的严重异常会导致宕机,捕获的异常可以被忽略,让代码继续运行。
Go语言没有异常系统,其使用 panic 触发宕机类似于其他语言的抛出异常,recover 的宕机恢复机制就对应其他语言中的 try/catch 机制。
下面的代码实现了 ProtectRun() 函数,该函数传入一个匿名函数或闭包后的执行函数,当传入函数以任何形式发生 panic 崩溃后,可以将崩溃发生的错误打印出来,同时允许后面的代码继续运行,不会造成整个进程的崩溃。
保护运行函数:
package main import ( "fmt" "runtime" ) // 崩溃时需要传递的上下文信息 type panicContext struct { function string // 所在函数 } // 保护方式允许一个函数 func ProtectRun(entry func()) { // 延迟处理的函数 defer func() { // 发生宕机时,获取panic传递的上下文并打印 err := recover() switch err.(type) { case runtime.Error: // 运行时错误 fmt.Println("runtime error:", err) default: // 非运行时错误 fmt.Println("error:", err) } }() entry() } func main() { fmt.Println("运行前") // 允许一段手动触发的错误 ProtectRun(func() { fmt.Println("手动宕机前") // 使用panic传递上下文 panic(&panicContext{ "手动触发panic", }) fmt.Println("手动宕机后") }) // 故意造成空指针访问错误 ProtectRun(func() { fmt.Println("赋值宕机前") var a *int *a = 1 fmt.Println("赋值宕机后") }) fmt.Println("运行后") }
代码输出结果:
运行前
手动宕机前
error: &{手动触发panic}
赋值宕机前
runtime error: runtime error: invalid memory address or nil pointer dereference
运行后
对代码的说明:
panic 和 recover 的组合有如下特性:
虽然 panic/recover 能模拟其他语言的异常机制,但并不建议在编写普通函数时也经常性使用这种特性。
在 panic 触发的 defer 函数内,可以继续调用 panic,进一步将错误外抛,直到程序整体崩溃。
如果想在捕获错误时设置当前函数的返回值,可以对返回值使用命名返回值方式直接进行设置。
当前名称:创新互联GO教程:Go语言宕机恢复(recover)——防止程序崩溃
网站URL:http://www.mswzjz.com/qtweb/news30/200030.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联