導讀:對于錯誤碼的設計,不同的開發團隊有不同的風格習慣,本文分享阿里文娛技術專家長統對于錯誤碼的看法,希望從錯誤碼使用的不同場景討論得到一個合理的錯誤碼規約,得到一個面向日志錯誤碼標準和一個面向外部傳遞的錯誤碼標準,
一 前言
在作業中,接觸過不少外部介面,其中包括:支付寶,微信支付,微博開發平臺,阿里云等等,每家公司錯誤碼風格都不盡相同,有使用純數字的,有使用純英文的,也有使用字母和數字組合的,也接觸過很多內部系統,錯誤碼設計也不盡相同,
錯誤碼的輸出路徑
面向日志輸出
-
服務內傳遞,最終是輸出到日志,
-
域內服務間,比如同時大麥電商之間的系統,最終目的是輸出到日志,
面向外部傳遞
-
域內向域外
-
服務端傳遞到前端
-
OpenAPI 錯誤碼
-
內部不同域之間
錯誤碼使用場景
-
通過錯誤碼配置監控大盤,
-
通過日志進行問題排查,快速定位問題,
-
后端服務之間錯誤碼傳遞,
-
前端展示的錯誤提示/OpenAPI,
本文希望從錯誤碼使用的不同場景討論得到一個合理的錯誤碼規約,得到一個面向日志錯誤碼標準和一個面向外部傳遞的錯誤碼標準,
PS:本文參考全部引自阿里巴巴《Java 開發手冊》,下稱《手冊》,
二 什么是錯誤碼
錯誤碼要回答的最根本的問題是,誰的錯?錯在哪?
那么一個錯誤能表示出誰的錯和錯在哪里就是一個好的錯誤碼嗎?答案顯然是否定的,這個標準太基礎了,
-
好的錯誤碼必須能夠快速知曉錯誤來源,
-
好的錯誤碼必須易于記憶和對比,
-
好的錯誤碼必須能夠脫離檔案和系統平臺達到線下輕量溝通的目的(這個要求比較高),
引自《手冊》- 例外日志-錯誤碼
錯誤碼的制定原則:快速溯源、簡單易記、溝通標準化,
說明:錯誤碼想得過于完美和復雜,就像康熙字典中的生僻字一樣,用詞似乎精準,但是字典不容易隨身攜帶并且簡單易懂,
正例:錯誤碼回答的問題是誰的錯?錯在哪?
1)錯誤碼必須能夠快速知曉錯誤來源,可快速判斷是誰的問題,
2)錯誤碼易于記憶和比對(代碼中容易 equals),
3)錯誤碼能夠脫離檔案和系統平臺達到線下輕量化地自由溝通的目的,
這個原則寫在例外日志-錯誤碼這個章節,我認為同樣適用在面向用戶的錯誤碼,
三 錯誤碼規范
錯誤碼定義要有字母也要有數字
純數字錯誤碼
錯誤碼即人性,感性認知+口口相傳,使用純數字來進行錯誤碼編排不利于感性記憶和分類,
說明:數字是一個整體,每位數字的地位和含義是相同的,
反例:一個五位數字 12345,第1位是錯誤等級,第 2 位是錯誤來源,345 是編號,人的大腦不會主動地分辨每位數字的不同含義,
《手冊》說明了純數字錯誤碼存在的問題,
純字母錯誤碼
那么純字母錯誤碼不香嗎?有兩個問題:
-
對于使用漢語的我們用英語去準確描述一個錯誤有時是比較困難的,
-
純英文字母的錯誤碼不利于排序,
錯誤碼盡量有利于不同文化背景的開發者進行交流與代碼協作,
說明:英文單詞形式的錯誤碼不利于非英語母語國家(如阿拉伯語、希伯來語、俄羅斯語等)之間的開發者互相協作,
快速溯源 | 簡單易記 | 溝通標準化
什么是快速溯源?就是一眼看上去就知道哪里出了什么問題,
李雷負責 A 服務,韓梅梅負責 B 服務,韓梅梅發現服務 B 出現了一個錯誤碼,韓梅梅能夠快速定位這是服務 A 的內部業務例外造成的問題,這個時候韓梅梅就可以拿著錯誤碼找到李雷說,"hi,Li Lei,How old are you,(李雷,怎么老是你)",李雷拿過來錯誤碼一看,內心萬馬奔騰,一下就能知道這是上游 Polly 負責的應用阿爾法出了錯,
怎么能達到這個效果呢?
-
首先要有一套標準并且在域內各個業務都在用同樣的標準,
-
其次要求錯誤碼有自我解釋的能力是有資訊含量的有意義,
-
最后在域內要傳遞錯誤碼,
錯誤碼標準的意義
開宗明義借用了《手冊》對于錯誤碼定義的原則作為錯誤碼規范能夠給我們帶來的收益,我想再次強調并且試著從反面闡述沒有錯誤碼標準會帶來的成本,
錯誤碼是用來做溝通的:系統與系統間的溝通,人與人間的溝通,人與系統間的溝通,
試想下面這個場景:
韓梅梅看到一個例外日志其中一個純數字的錯誤碼,
韓梅梅需要理解這串數字代表的是什么,它到底是不是一個錯誤碼,經過幾秒鐘確定下來這是一個錯誤碼,但她不能確定這是不是本系統中錯誤碼,因為在她負責的系統是由韓梅梅、Lucy 和 Lily 三個人共同維護的,每個人都按照自己的理解定義了一套錯誤碼,
韓梅梅去系統原始碼中查找這個錯誤碼,但是發現這個錯誤碼并不是本系統的錯誤碼,
然后再前翻兩頁后翻兩頁從日志背景關系中確定這是李雷負責系統的錯誤碼,“Li Lie,how old are you?”,
韓梅梅把錯誤碼甩到李雷臉上,李雷一臉懵逼,這是我的系統的錯誤碼嗎?
李雷也不確定,因為李雷負責的系統是由李雷、林濤和 Jim 維護的,也是三人共同維護的,
李雷只好打開原始碼,還真是!
上邊的場景經過了發現-初判斷-判斷來源-確定來源-溝通-二次判斷-二次確認七個步驟,
希望上邊的場景描述能夠說明沒有統一標準的錯誤所帶來的成本,
四 面向日志的錯誤碼
輸出到日志的錯誤碼有兩個用途:
-
用來快速溯源找到問題,
-
用來形成監控大盤,
錯誤碼設計
《手冊》對于錯誤碼的建議有非常多的可取參考的地方:
錯誤碼不體現版本號和錯誤等級資訊,
說明:錯誤碼以不斷追加的方式進行兼容,錯誤等級由日志和錯誤碼本身的釋義來決定,
錯誤碼為字串型別,共 5 位,分成兩個部分:錯誤產生來源+四位數字編號,
錯誤碼不能直接輸出給用戶作為提示資訊使用,
說明:堆疊(stack_trace)、錯誤資訊(error_message)、錯誤碼(error_code)、提示資訊(user_tip)是一個有效關聯并互相轉義的和諧整體,但是請勿互相越俎代庖,
在獲取第三方服務錯誤碼時,向上拋出允許本系統轉義,由 C 轉為 B,并且在錯誤資訊上帶上原有的第三方錯誤碼,
結合錯誤碼設計原則、錯誤碼用途、規約建議,面向服務端日志的錯誤碼應該是如下形式,
錯誤碼分為一級宏觀錯誤碼、二級宏觀錯誤碼、三級宏觀錯誤碼,
錯誤碼即人性,感性認知+口口相傳,使用純數字來進行錯誤碼編排不利于感性記憶和分類,
說明:數字是一個整體,每位數字的地位和含義是相同的,
反例:一個五位數字 12345,第 1 位是錯誤等級,第 2 位是錯誤來源,345 是編號,人的大腦不會主動地分辨每位數字的不同含義,
按照《手冊》的建議設計出的面向日志的錯誤碼定義共十三位(十位有意義,三位連接符),并且應該具有如下分類:
-
應用標識,表示錯誤屬于哪個應用,三位數字,
-
功能域標識,表示錯誤屬于應用中的哪個功能模塊,三位數字,
-
錯誤型別,表示錯誤屬于那種型別,一位字母,
-
錯誤編碼,錯誤型別下的具體錯誤,三位數字,

《手冊》還有一條是規定錯誤碼應該如何定義:
錯誤碼為字串型別,共 5 位,分成兩個部分:錯誤產生來源+四位數字編號,
說明:錯誤產生來源分為 A/B/C,A 表示錯誤來源于用戶,比如引數錯誤,用戶安裝版本過低,用戶支付超時等問題;B 表示錯誤來源于當前系統,往往是業務邏輯出錯,或程式健壯性差等問題;C 表示錯誤來源于第三方服務,比如 CDN 服務出錯,訊息投遞超時等問題;四位數字編號從 0001 到 9999,大類之間的步長間距預留 100,
五位錯誤碼的好處是易記,但是對于面向日志的錯誤碼場景利用錯誤碼制作需要分類的業務監控大盤將變得比較困難,比如統計應用 A 的功能 B 的錯誤出現次數,
同樣在系統間傳遞這個型別的錯誤碼非常有可能發生錯誤碼沖突,
當然對于分為四段的錯誤碼同樣尤其不好的一面,應用標識和功能域標識需要有專人去管理或者開發一個錯誤碼管理工具,否則時間一長很容易產生定義的混亂形成破窗,
《手冊》對于錯誤碼定義我認為非常適合面向外部傳遞的錯誤碼,簡單、易記、是大家熟悉的錯誤碼樣式,并且透出的錯誤碼數量是非常有限的,
不用列舉定義錯誤碼
國際化支持是一個不使用列舉定義錯誤碼很重要的理由,
我們通過 i18n 的支持可以做到錯誤碼、錯誤狀態、錯誤描述的管理,
五 面向外部傳遞的錯誤碼
面向外部傳遞的錯誤碼是為了把域內的錯誤資訊傳遞出去,
可以讓域外系統通過錯誤碼進行錯誤碼進行后續的動作或是中斷操作或是記錄日志繼續執行,
可以讓前端通過錯誤碼給出用戶準確的錯誤提示或者忽略錯誤進行重試,
錯誤碼設計
根據《手冊》給出的錯誤碼定義建議設計出的面向外部傳遞的錯誤碼共五位,并且有如下分類:
-
錯誤型別,表示錯誤來源,一位字母,
-
錯誤編碼,表示具體錯誤,四位數字,

錯誤碼的后三位編號與 HTTP 狀態碼沒有任何關系,
錯誤碼即人性,感性認知+口口相傳,使用純數字來進行錯誤碼編排不利于感性記憶和分類,
說明:數字是一個整體,每位數字的地位和含義是相同的,
反例:一個五位數字 12345,第1位是錯誤等級,第 2 位是錯誤來源,345 是編號,人的大腦不會主動地分辨每位數字的不同含義,
下圖是《手冊》給出的錯誤碼示例:
他山之石
他山之石不一定能攻玉,
谷歌 API 錯誤碼定義
谷歌 API 的錯誤碼定義與 HTTP 狀態碼有著非常強的聯系,并且是一個全數字錯誤碼定義,
沒有明顯的錯誤分類,快速識別和自解釋能力比較弱,
騰訊 OpenAPI(文智)錯誤碼定義
這也是一個全數字的錯誤碼,沒有明確的分類欄位,純數字的某一位已看不出明顯的分類,
不利于進行感性記憶,
微博 API 錯誤碼定義
同樣是全數字的錯誤碼定義:
其他建議
《手冊》中有一條建議:
全部正常,但不得不填充錯誤碼時回傳五個零:00000,
這也是在其他家 API 錯誤碼中能夠看到的定義,
參考
《阿里巴巴java開發手冊》《Google API Design Guide 》(https://www.bookstack.cn/books/API-design-guide)
《阿里云-檔案存盤-錯誤碼》(https://help.aliyun.com/document_detail/62603.html)
《微博開放平臺-API-錯誤碼》(https://open.weibo.com/wiki/Help/error)
《騰訊開放平臺-錯誤碼》(https://wiki.open.qq.com/wiki/%E9%94%99%E8%AF%AF%E7%A0%81)
本文來自博客園,作者:古道輕風,轉載請注明原文鏈接:https://www.cnblogs.com/88223100/p/How-to-design-the-error-code-reasonably.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/528103.html
標籤:其他
