概述:使用事務一定要關閉!(心急的可以直接看這句,趕緊去檢查下自己的代碼)
我們golang項目用的gorm,最近pre測試跑腳本時,總會出現504,某個接口不可用。分析了半天pprof,阻塞數量較多的goroutine,某些時候並不能看到真實問題的所在。
出現504,通過pprof:debug/pprof/goroutine?debug=2 或者debug/pprof/goroutine?debug=1 能看到阻塞的goroutine,處在io wait狀態
檢查下pod內,連接數(netstat),發現http的連接數和mysql的連接數暴增!!!
導致mysql的連接數暴增常見的有兩種:
1、使用事務,沒有關閉~!!!!! (我們小伙伴的錯誤命中)
tx:=db.conn后,err判斷,直接return,沒有進行tx.rollback。這時候mysql的conn_pool會+1,且不可復用。
錯誤的請求繼續上漲后,就會出現連接數打滿,繼而新的請求一直阻塞,goroutine也會阻塞住
正確使用:
conn, err := mysql.GetConn() if err != nil { return } tx := conn.Begin() defer func() { if r := recover(); r != nil { tx.Rollback() } }() if err != nil { tx.Rollback() return }
2、使用rows方法請一定要關閉連接。rows請一定要在err==nil的情況下使用,不然會導致空指針panic。
rows, err := db.rows() if err != ni { return err } defer rows.close()
3、使用事務,切記
tx := conn.Begin()
下面一定使用tx,不要用conn了!!!!