Go语言宕机恢复我有小妙招
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 运行后 对代码的声名:第 9 行声明描写错误的布局体,生涯执行错误的函数。 第 17 行行使 defer 将闭包耽误执行,当 panic 触发瓦解时,ProtectRun() 函数将竣事运行,此时 defer 后的闭包将会产生挪用。 第 20 行,recover() 获取到 panic 传入的参数。 第 22 行,行使 switch 对 err 变量举办范例断言。 第 23 行,假如错误是有 Runtime 层抛出的运行时错误,如空指针会见、除数为 0 等环境,打印运行时错误。 第 25 行,其他错误,打印转达过来的错误数据。 第 44 行,行使 panic 手动触发一个错误,并将一个布局体附带信息转达已往,此时,recover 就会获取到这个布局体信息,并打印出来。 第 57 行,模仿代码中空指针赋值造成的错误,此时会由 Runtime 层抛堕落误,被 ProtectRun() 函数的 recover() 函数捕捉到。 (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |