Go高級特性探究之recover捕獲panic詳解
在Go語言中,當(dāng)程序出現(xiàn)panic(即運行時錯誤)時,程序會立即停止當(dāng)前的執(zhí)行流程,并在函數(shù)調(diào)用堆棧向上逐層返回,直到遇到recover函數(shù)或程序終止為止。
而recover函數(shù)的作用就是捕獲這個panic,并恢復(fù)正常的執(zhí)行流程。在Gin框架中,提供了recover中間件來自動捕獲panic,并轉(zhuǎn)換為HTTP 500錯誤返回給客戶端。
使用
使用recover中間件非常簡單,只需要在Gin路由中添加即可:
router := gin.Default() router.Use(gin.Recovery())
需要注意的是,recover中間件應(yīng)該在Gin路由中的第一個聲明,以確??梢圆东@所有的panic。
配合日志打印與埋點上報
在API開發(fā)中,當(dāng)用戶請求接口時,有時候會遇到一些問題,如訪問url錯誤、參數(shù)錯誤、數(shù)據(jù)庫連接超時等。雖然recover中間件可以避免由程序錯誤導(dǎo)致的panic,但仍然需要記錄這些錯誤信息來協(xié)助問題的排查和定位。
因此,我們可以配合日志打印和埋點上報來記錄這些錯誤。以日志打印為例,Gin框架提供了官方的Logger中間件,可以使用Logger來記錄錯誤信息:
router := gin.Default() // Logger 中間件將請求的URL、響應(yīng)時間、響應(yīng)狀態(tài)碼和請求的IP地址寫入日志文件 router.Use(gin.Logger()) // Recover 中間件將 panic 轉(zhuǎn)換為 500 錯誤,并寫入日志文件 router.Use(gin.Recovery()) // 業(yè)務(wù)代碼 router.GET("/api", func(c \*gin.Context) { ? ? // code ? ? if err != nil { ? ? ? ? // 某個函數(shù)拋出了 panic ? ? ? ? log.Printf("\[ERROR] - %v\n", err) ? ? ? ? c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{ ? ? ? ? ? ? "message": "內(nèi)部錯誤,請稍后重試", ? ? ? ? }) ? ? ? ? return ? ? } ? ? // code })
在上述代碼中,我們使用log來記錄錯誤信息,并在響應(yīng)中返回了錯誤提示。這樣我們就能及時的發(fā)現(xiàn)問題并進(jìn)行排查了。
當(dāng)然,我們還可以在記錄錯誤信息的同時上傳到埋點工具中,例如Sentry、Zipkin
等,來實現(xiàn)自動的錯誤上報和監(jiān)控。
recover在開源項目中的使用
recover中間件在開源項目中廣泛應(yīng)用,例如Prometheus、etcd、Kubernetes等項目中都有使用。
以etcd為例,它使用recover中間件捕獲所有的panic,并在日志中記錄錯誤信息,如下所示:
func (s *EtcdServer) recoverAndLog(rctx rpctypes.Context, w http.ResponseWriter, req *http.Request) { ? ? data, err := ioutil.ReadAll(req.Body) ? ? if err != nil { ? ? ? ? writeError(w, rctx, err) ? ? ? ? return ? ? } ? ? defer func() { ? ? ? ? if v := recover(); v != nil { ? ? ? ? ? ? log.Printf("panic: %v", v) ? ? ? ? ? ? writeError(w, rctx, fmt.Errorf("panic: %v", v)) ? ? ? ? } ? ? }() ? ? // code }
在該函數(shù)中,使用了defer關(guān)鍵字調(diào)用recover函數(shù)捕獲panic,并使用log記錄錯誤信息并返回錯誤提示。
總結(jié)
通過Gin框架中的recover中間件,我們可以方便的捕獲和處理程序運行時的錯誤,從而提高了API服務(wù)的穩(wěn)定性和可靠性。同時,配合日志打印和埋點上報,可以更好地記錄錯誤信息和輔助問題的排查和解決。在開源項目中,recover中間件也被廣泛應(yīng)用,并幫助了很多項目實現(xiàn)了穩(wěn)定的運行。
到此這篇關(guān)于Go高級特性探究之recover捕獲panic詳解的文章就介紹到這了,更多相關(guān)Go recover捕獲panic內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
go語言int64整型轉(zhuǎn)字符串的實現(xiàn)
本文主要介紹了go語言int64整型轉(zhuǎn)字符串的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03Golang 標(biāo)準(zhǔn)庫 tips之waitgroup詳解
本篇文章給大家介紹Golang 標(biāo)準(zhǔn)庫 tips之waitgroup的相關(guān)知識,包括使用 channel 實現(xiàn) WaitGroup 的功能介紹,感興趣的朋友跟隨小編一起看看吧2021-07-07Golang 函數(shù)執(zhí)行時間統(tǒng)計裝飾器的一個實現(xiàn)詳解
這篇文章主要介紹了Golang 函數(shù)執(zhí)行時間統(tǒng)計裝飾器的一個實現(xiàn)詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-03-03詳解Go語言如何利用高階函數(shù)寫出優(yōu)雅的代碼
高階函數(shù)(Hiher-order?Function)定義為:滿足下列條件之一的函數(shù):接收一個或多個函數(shù)作為參數(shù);返回值是一個函數(shù)。本文為大家介紹了如何利用高階函數(shù)寫出優(yōu)雅的代碼,希望對大家有所幫助2023-01-01Go|使用Options模式和建造者模式創(chuàng)建對象實戰(zhàn)
這篇文章主要介紹了Go使用Options模式和建造者模式創(chuàng)建對象實戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04