前言

总结一下,也许时间久了,一些方法就忘了。下面的方法都是实战中用过的,各有适用场景。

一、卡死、go程泄露–获取调用栈

1.go build -race编译选项

适用于开发自测,和线上少量灰度。使用简单只要加上-race选项就行。 有线程不安全的代码会打印出调用栈
假如服务端卡死,客户端请求过来,会增加go程,超过4096(记得不是太清楚)的样子,进程就会退出,然后打印所有调用栈 对了,如果是正式上线的服务,需要把-race选项去除
注意 :使用带race选项编译,如果你的服务有问题。进程会退出的。
最佳实践 :对于长期跑的服务,怎么处理race选项,在服务第一个版本上线,可以少量灰度加race选项

1
go build -race example.go

2. kill -6 pid方式

这个方法不依赖go的工具链,适合手头没有趁手工具,通过发送信号的方式,让进程打印所有调用栈到stdout上。
缺点:会把进程杀死

3. 使用dlv调试

dlv对于golang,就像gdb对于c一样,重要性和位置不言而喻。

  • 安装
1
go get -u github.com/derekparker/delve/cmd/dlv
  • 挂载到进程里面 dlv的一些命令和gdb类似,以前调试c经常用gdb attach pid挂载到进程看所有线程
1
dlv attach pid
  • 显示所有协程
1
goroutines
  • 切换线程 id是通过goroutines 得到的数字
1
goroutine id
  • 打印当前调用栈
1
bt

二、内存

1. ps方式

如果是运行中的进程,把进程名换成你实际的服务名,通过观察ps命令第5列得到虚拟内存, 第6列得到物理内存

1
ps aux |grep process_name|grep -v grep|awk '{print $5, $6}'

然后导入数据到execl里面画一个曲线,观察下内存趋势。这个方法也适用于c/c++ 然后先观察调用栈,可以回到第一个方法

2. pprof方法

pprof查看内存使用

  • 导入包路径
1
_ "net/http/pprof"
  • 启动http服务
1
http.ListenAndServe("localhost:8082", nil)
  • 查看内存使用
1
go tool pprof http://localhost:8082/debug/pprof/heap

pprof其他用法记录

  • 查看阻塞go程
1
go tool pprof http://localhost:8082/debug/pprof/block