Go语言中的宕机panic-程序终止运行

参考:
http://c.biancheng.net/view/63.html

关键点

希望通过下面的关键词,能够实现目的:能够快速回忆理解复习 知识点:

1、宕机panic, 会造成程序崩溃

2、defer先执行 还是 panic先执行?

  • panic语句的defer是不执行的,

  • panic 会 触发在panic语句声明的defer语句,简单的说,就是defer先执行。

3、如何触发panic?

方式一:手动触发

方式二:运行依赖的资源缺失时,引发的宕机panic

4、panic 使用的场景?或者说,是使用panic还是error呢?

A、panic适用于严重错误时,使用的。

B、大部分场景,还是使用error比较好

5、使用宕机panic的好处

A、即使的止损,防止错误继续扩大

B、输出堆栈等信息,有利于分析错误原因

Go语言的类型系统会在编译时捕获很多错误,但有些错误只能在运行时检查,如数组访问越界、空指针引用等,这些运行时错误会引起宕机。

宕机不是一件很好的事情,可能造成体验停止、服务中断,就像没有人希望在取钱时遇到 ATM 机蓝屏一样,但是,如果在损失发生时,程序没有因为宕机而停止,那么用户将会付出更大的代价,这种代价可以是金钱、时间甚至生命,因此,宕机有时也是一种合理的止损方法。

一般而言,当宕机发生时,程序会中断运行,并立即执行在该 goroutine(可以先理解成线程)中被延迟的函数(defer 机制),随后,程序崩溃并输出日志信息,日志信息包括 panic value 和函数调用的堆栈跟踪信息,panic value 通常是某种错误信息。

对于每个 goroutine,日志信息中都会有与之相对的,发生 panic 时的函数调用堆栈跟踪信息,通常,我们不需要再次运行程序去定位问题,日志信息已经提供了足够的诊断依据,因此,在我们填写问题报告时,一般会将宕机和日志信息一并记录。

虽然Go语言的 panic 机制类似于其他语言的异常,但 panic 的适用场景有一些不同,由于 panic 会引起程序的崩溃,因此 panic 一般用于严重错误,如程序内部的逻辑不一致。任何崩溃都表明了我们的代码中可能存在漏洞,所以对于大部分漏洞,我们应该使用Go语言提供的错误机制,而不是 panic。

1、手动触发宕机

Go语言可以在程序中手动触发宕机,让程序崩溃,这样开发者可以及时地发现错误,同时减少可能的损失。

Go语言程序在宕机时,会将堆栈和 goroutine 信息输出到控制台,所以宕机也可以方便地知晓发生错误的位置,那么我们要如何触发宕机呢,示例代码如下所示:

package main
func main() {
    panic("crash")
}
代码运行崩溃并输出如下:
panic: crash

goroutine 1 [running]:
main.main()
    D:/code/main.go:4 +0x40
exit status 2

以上代码中只用了一个内建的函数 panic() 就可以造成崩溃,panic() 的声明如下:

func panic(v interface{})    //panic() 的参数可以是任意类型的。

2、在运行依赖的必备资源缺失主动触发宕机

regexp 是Go语言的正则表达式包,正则表达式需要编译后才能使用,而且编译必须是成功的,表示正则表达式可用。

编译正则表达式函数有两种,具体如下:

1) func Compile(expr string) (*Regexp, error)

编译正则表达式,发生错误时返回编译错误同时返回 Regexp 为 nil,该函数适用于在编译错误时获得编译错误进行处理,同时继续后续执行的环境。

2) func MustCompile(str string) *Regexp

当编译正则表达式发生错误时,使用 panic 触发宕机,该函数适用于直接使用正则表达式而无须处理正则表达式错误的情况。

MustCompile 的代码如下:

func MustCompile(str string) *Regexp {
    regexp, error := Compile(str)
    if error != nil {
        panic(`regexp: Compile(` + quote(str) + `): ` + error.Error())
    }
    return regexp
}

代码说明如下:

  • 第 1 行,编译正则表达式函数入口,输入包含正则表达式的字符串,返回正则表达式对象。
  • 第 2 行,Compile() 是编译正则表达式的入口函数,该函数返回编译好的正则表达式对象和错误。
  • 第 3 和第 4 行判断如果有错,则使用 panic() 触发宕机。
  • 第 6 行,没有错误时返回正则表达式对象。

手动宕机进行报错的方式不是一种偷懒的方式,反而能迅速报错,终止程序继续运行,防止更大的错误产生,不过,如果任何错误都使用宕机处理,也不是一种良好的设计习惯,因此应根据需要来决定是否使用宕机进行报错。

3、在宕机触发延迟执行语句defer

当 panic() 触发的宕机发生时,panic() 后面的代码将不会被运行,但是在 panic() 函数前面已经运行过的 defer 语句依然会在宕机发生时发生作用,参考下面代码:

package main
import "fmt"
func main() {
    defer fmt.Println("宕机后要做的事情1")
    defer fmt.Println("宕机后要做的事情2")
    panic("宕机")
}

代码输出如下:

宕机后要做的事情2
宕机后要做的事情1
panic: 宕机

goroutine 1 [running]:
main.main()
    D:/code/main.go:8 +0xf8
exit status 2

对代码的说明:

第 6 行和第 7 行使用 defer 语句延迟了 2 个语句。
第 8 行发生宕机。

宕机前,defer 语句会被优先执行,由于第 7 行的 defer 后执行,因此会在宕机前,这个 defer 会优先处理,随后才是第 6 行的 defer 对应的语句,这个特性可以用来在宕机发生前进行宕机信息处理。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容