golang高级调式
程序延时太大
案例:一次gc stw 高达170ms

修复:降低gc频率debug.SetGCPercent(1000)
程序假死、阻塞问题
curl $ip:$port/deug/pprof/goroutine?debug=1 -o /tmp/debug1.html 输出各个goroutine堆栈信息
curl $ip:$port/deug/pprof/head?debug=1 -o /tmp/debug1.html 输出内存占用信息
注意:必须带上debug=1或者=2参数,否则,生成的文件是乱码
离线pprof
curl 127.0.0.1:6060/debug/pprof/profile -o /tmp/cpu_76.html
go tool pprof -http=10.179.64.102:8081 /root/cpu_76.html
程序异常退出(没任何日志)
-
可以捕获的panic
包括:- 数组 ( slice ) 下标越界
- 访问未初始化的指针或 nil 指针【比如当err为nil时调用err.Error()】
- 试图往已经 close 的 chan 里发送数据
- 类型断言(断言错误,且没有使用ok判断)
处理:在所有goroutine的最外层增加recover,输出堆栈信息。因为任何goroutine发生panic,如果没有recover,都会导致整个程序crash
defer func() {
if err := recover(); err != nil {
buf := make([]byte, 64<<10)
n := runtime.Stack(buf, false)
buf = buf[:n]
fmt.Errorf("=== recovery ===: %v: \n%s\n", err, buf)
return err
}
}()
注意:直接写defer recover(),无法阻止panic,必须要将recover()放到func()里面; recover不能跨goroutine
-
无法捕获的panic
recover 并非万能,它只针对用户态下的 panic 关键字有效。还存在一些无法恢复的 ”恐慌“,比如像是fatalthrow、fatalpanic 等等方法,是直接退出程序,结果是中断程序。- 并发读写map "fatal error: concurrent map read and map write"
[runtime 中调用 throw 函数抛出的异常是无法在业务代码中通过 recover 捕获的]
![]()
处理:在启动命令前增加"export GOTRACEBACK=crash",当异常退出时会生成coredump,然后可以用dlv调试
- 并发读写map "fatal error: concurrent map read and map write"
-
检查系统日志,是否有oom日志。/var/log/message


浙公网安备 33010602011771号