背景:
項(xiàng)目運(yùn)行過程中會(huì)出現(xiàn)各種各樣的問題,常見的有以下幾種情況:
- 業(yè)務(wù)流程分析疏漏,對(duì)業(yè)務(wù)流程的反向操作、邊界分析設(shè)計(jì)不充分
- 調(diào)用外部服務(wù)、調(diào)用外部系統(tǒng)出現(xiàn)的超時(shí)、錯(cuò)誤、返回值與預(yù)期不符
- 外部資源連通性問題,db等服務(wù)器出現(xiàn)的網(wǎng)絡(luò)抖動(dòng)或宕機(jī)
無論是分析設(shè)計(jì)、開發(fā)、測(cè)試、線上都需要能夠準(zhǔn)確定位問題并制定解決方案。
目的:
- 規(guī)范化異常的處理過程,避免異常被吞和到處都在捕獲異常的情況
- 準(zhǔn)確的反饋異常信息,為定位問題提供依據(jù)
- 通用性異常全局處理,降低業(yè)務(wù)開發(fā)關(guān)注度
- 對(duì)異常情況進(jìn)行預(yù)警,以便能夠及時(shí)響應(yīng)
一、異常規(guī)劃
1. 業(yè)務(wù)類異常
造成業(yè)務(wù)流程不能正確執(zhí)行的行為,常見的幾種:
- 輸入必填驗(yàn)證
- 業(yè)務(wù)狀態(tài)約束校驗(yàn)
- 權(quán)限驗(yàn)證
- 調(diào)用外部服務(wù)返回?cái)?shù)據(jù)不符合預(yù)期
這類異常需要給調(diào)用方返回明確的異常描述信息,一般情況下和代碼無關(guān),無需調(diào)整編碼
注:是業(yè)務(wù)完整性的一部分,需提前分析
2. 系統(tǒng)類異常
服務(wù)調(diào)用異常: 超時(shí)、中斷、接口異常(非200請(qǐng)求)
第三方異常 :db\redis\消息隊(duì)列 連接失敗等
注:通常與業(yè)務(wù)流程無關(guān),與第三方系統(tǒng)有關(guān),不能簡(jiǎn)單的通過調(diào)整代碼解決
3. 通用異常
編碼不嚴(yán)謹(jǐn)、數(shù)據(jù)異常造成的問題,不可預(yù)測(cè)
舉例:參數(shù)類型不匹配、空指針、數(shù)組越界
二、異常攔截
在springboot中全局異常攔截處理已知的有下面2種方案:
方案1:@controlleradvice、實(shí)現(xiàn)errorcontroller
注:利用springboot自帶的攔截機(jī)制,只需要定義出處理的策略,沒有破壞springboot的約定
方案2:繼承abstracthandlerexceptionresolver,完全自定義處理策略
注:使用spring中最底層的類,打破了springboot的約定,能夠攔截到所有異常
三、方案實(shí)踐
筆者基于方案一進(jìn)行實(shí)踐。
1. 異常攔截時(shí)序圖
2. rrcrestadvice實(shí)現(xiàn)代碼
2. rrcexphandler實(shí)現(xiàn)代碼
注意:基于restcontrolleradvice的異常攔截只能捕獲請(qǐng)求達(dá)controller之后的程序異常,所以需要實(shí)現(xiàn)errorcontroller處理之前的異常。
總結(jié):
推薦基于springboot中@controlleradvice 和 errorcontroller接口的約定,相對(duì)較符合springboot的約定。
其他可選方案:
繼承abstracthandlerexceptionresolver
優(yōu)點(diǎn):可完全自定義處理策略。缺點(diǎn):對(duì)框架約定破壞較為嚴(yán)重,自定義處理策略容易疏漏。
繼承handlerinterceptoradapter
理論上可以處理業(yè)務(wù)代碼拋出的異常,優(yōu)缺點(diǎn)沒有進(jìn)行過驗(yàn)證。
好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)服務(wù)器之家的支持。
原文鏈接:http://www.cnblogs.com/yuhuashang-edward/p/10076217.html