在go語(yǔ)言中使用delve調(diào)試工具診斷協(xié)程泄露流程步驟示例
Go  /  管理員 發(fā)布于 9個(gè)月前   500
使用delve 調(diào)試工具, 不用改代碼,直接現(xiàn)場(chǎng)診斷Go協(xié)程泄露問(wèn)題。
安裝 delve
在開(kāi)發(fā)環(huán)境,我們安裝個(gè)軟件當(dāng)然是易如反掌。
但是要在生產(chǎn)環(huán)境,服務(wù)器上安裝東西,那就說(shuō)不準(zhǔn)有多少艱難險(xiǎn)阻了。
delve 一般是通過(guò)命令
go install github.com/go-delve/delve/cmd/dlv@master
安裝。
但是就要求服務(wù)器安裝了 go 并且能夠連接外部網(wǎng)絡(luò)。
這已經(jīng)是比較苛刻的要求了。
最低要求就是能夠連接服務(wù)器,并且能夠把 delve 傳上去。
否則就不太好辦了。
如果是通過(guò)鏡像部署的應(yīng)用,我覺(jué)得在打鏡像時(shí)把 delve 添加進(jìn)去是個(gè)不錯(cuò)的主意,體積不大,
還能防不時(shí)之需。
連接程序
第二步就是連接程序,開(kāi)始 debug 了,這個(gè)比較簡(jiǎn)單,兩個(gè)命令就能解決
ps -aux |grep $name # 查詢 pid, $name 替換為程序名字
dlv attach $pid # 連接程序,$pid 替換為上一步查詢到的 pid
顯示協(xié)程信息
在執(zhí)行 dlv attach 命令后,就會(huì)進(jìn)入 dlv 的交互控制臺(tái)。
最簡(jiǎn)單的話,輸入 grs 就能顯示協(xié)程信息,但在協(xié)程泄露的情況下,
做一些過(guò)濾和分組可以看的更清楚一點(diǎn),
命令如下:
grs -w user -group goloc
表示只顯示用戶協(xié)程,并按調(diào)起協(xié)程的位置分組統(tǒng)計(jì)。
詳細(xì)信息可以通過(guò) help grs 命令查看
測(cè)試演示
下面我用一個(gè)非常經(jīng)典的協(xié)程泄露場(chǎng)景來(lái)演示下
func main() {
for {
queryAll()
}
}
func queryAll() int {
ch := make(chan int)
for i := 0; i < 3; i++ {
go func() { ch <- query() }()
}
return <-ch
}
func query() int {
n := rand.Intn(100) + 100
time.Sleep(time.Duration(n) * time.Millisecond)
return n
}
這個(gè)代碼模擬了 只取返回最快的結(jié)果,其他結(jié)果被遺棄后一直阻塞發(fā)送協(xié)程的情況。
運(yùn)行程序一段時(shí)間后,用 dlv 執(zhí)行
grs -w user -group goloc
后輸出是這樣的:
Type 'help' for list of commands.
(dlv) grs -w user -group goloc
<autogenerated>:1 in runtime.newproc
Goroutine 1 - User: C:/Work/my-project/learn/main.go:19 main.queryAll (0x8dba37) [chan receive]
Total: 1
C:/Work/my-project/learn/main.go:17 in main.queryAll
Goroutine 18 - User: C:/Work/my-project/learn/main.go:17 main.queryAll.func1 (0x8dba90) [chan send]
Goroutine 6 - User: C:/Work/my-project/learn/main.go:17 main.queryAll.func1 (0x8dba90) [chan send]
Goroutine 7 - User: C:/Work/my-project/learn/main.go:17 main.queryAll.func1 (0x8dba90) [chan send]
Goroutine 19 - User: C:/Work/my-project/learn/main.go:17 main.queryAll.func1 (0x8dba90) [chan send]
Goroutine 51 - User: C:/Work/my-project/learn/main.go:17 main.queryAll.func1 (0x8dba90) [chan send]
Total: 333
(dlv)
可以看到,queryAll 一共有 333 個(gè)協(xié)程,并都處于 chan send 狀態(tài)。
說(shuō)明發(fā)送被阻塞了,有了這個(gè)信息,問(wèn)題就很清晰明白了。
注意事項(xiàng)
dlv debug 時(shí)也會(huì)使得內(nèi)存占用變高,如果內(nèi)存已經(jīng)過(guò)高,那么可能加快引起 OOM。
123 在
Clash for Windows作者刪庫(kù)跑路了,github已404中評(píng)論 按理說(shuō)只要你在國(guó)內(nèi),所有的流量進(jìn)出都在監(jiān)控范圍內(nèi),不管你怎么隱藏也沒(méi)用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最簡(jiǎn)單的方法中評(píng)論 好久好久都沒(méi)看友情鏈接申請(qǐng)了,今天剛看,已經(jīng)添加。..博主 在
佛跳墻vpn軟件不會(huì)用?上不了網(wǎng)?佛跳墻vpn常見(jiàn)問(wèn)題以及解決辦法中評(píng)論 @1111老鐵這個(gè)不行了,可以看看近期評(píng)論的其他文章..1111 在
佛跳墻vpn軟件不會(huì)用?上不了網(wǎng)?佛跳墻vpn常見(jiàn)問(wèn)題以及解決辦法中評(píng)論 網(wǎng)站不能打開(kāi),博主百忙中能否發(fā)個(gè)APP下載鏈接,佛跳墻或極光..路人 在
php中使用hyperf框架調(diào)用訊飛星火大模型實(shí)現(xiàn)國(guó)內(nèi)版chatgpt功能示例中評(píng)論 教程很詳細(xì),如果加個(gè)前端chatgpt對(duì)話頁(yè)面就完美了..
Copyright·? 2019 侯體宗版權(quán)所有·
粵ICP備20027696號(hào)