阿里java開發手冊學習筆記(二、 異常日誌)

(一)異常處理

  1. Java 類庫中定義的可以通過預檢查方式規避的 RuntimeException 異常不應該過 catch 的方式來處理,比如:NullPointerException,IndexOutOfBoundsException 等。
  2. 異常不要用來做流程控制,條件控制。
  3. catch 時請分清穩定代碼和非穩定代碼,穩定代碼指的是無論如何不會出錯的代碼對於非穩定代碼的 catch 儘可能進行區分異常類型,再做對應的異常處理。
  4. 捕獲異常是爲了處理它,不要捕獲了卻什麼都不處理而拋棄之,如果不想處理它請將該異常拋給它的調用者。最外層的業務使用者,必須處理異常,將其轉化爲用戶可以解的內容。
  5. 有 try 塊放到了事務代碼中,catch 異常後,如果需要回滾事務,一定要注意手動滾事務。
  6. finally 塊必須對資源對象、流對象進行關閉,有異常也要做 try-catch。
  7. 不要在 finally 塊中使用 return
  8. 捕獲異常與拋異常,必須是完全匹配,或者捕獲異常是拋異常的父類。
  9. 在調用 RPC、二方包、或動態生成類的相關方法時,捕捉異常必須使用 Throwable類來進行攔截。
  10. 方法的返回值可以爲 null,不強制返回空集合,或者空對象等,必須添加註釋充分說明什麼情況下會返回 null 值。
  11. 防止 NPE,是程序員的基本修養,注意 NPE 產生的場景:
    1) 返回類型爲基本數據類型,return 包裝數據類型的對象時,自動拆箱有可能產生 NPE。
    反例:public int f() { return Integer 對象}, 如果爲 null,自動解箱拋 NPE。
    2) 數據庫的查詢結果可能爲 null。
    3) 集合裏的元素即使 isNotEmpty,取出的數據元素也可能爲 null。
    4) 遠程調用返回對象時,一律要求進行空指針判斷,防止 NPE。
    5) 對於 Session 中獲取的數據,建議進行 NPE 檢查,避免空指針。
    6) 級聯調用 obj.getA().getB().getC();一連串調用,易產生 NPE。
    正例:使用 JDK8 的 Optional 類來防止 NPE 問題。
  12. 定義時區分 unchecked / checked 異常,避免直接拋出 new RuntimeException(),更不允許拋出 Exception 或者 Throwable,應使用有業務含義的自定義異常。推薦業界已定義過的自定義異常,如:DAOException / ServiceException 等。
  13. 對於公司外的 http/api 開放接口必須使用“錯誤碼”;而應用內部推薦異常拋出;跨應用間 RPC 調用優先考慮使用 Result 方式,封裝 isSuccess()方法、“錯誤碼”、“錯誤簡短信息”。
  14. 避免出現重複的代碼(Don’t Repeat Yourself),即 DRY 原則。

(二)日誌規約

  1. 應用中不可直接使用日誌系統(Log4j、Logback)中的 API,而應依賴使用日誌框架SLF4J 中的 API,使用門面模式的日誌框架,有利於維護和各個類的日誌處理方式統一。
  2. 所有日誌文件至少保存 15 天,因爲有些異常具備以“周”爲頻次發生的特點。網絡運行狀態、安全相關信息、系統監測、管理後臺操作、用戶敏感操作需要留存相關的網絡日誌不少於 6 個月。
  3. 應用中的擴展日誌(如打點、臨時監控、訪問日誌等)命名方式:
    appName_logType_logName.log。logType:日誌類型,如 stats/monitor/access 等;logName:日誌描述。這種命名的好處:通過文件名就可知道日誌文件屬於什麼應用,什麼類型,什麼目的,也有利於歸類查找。
  4. 在日誌輸出時,字符串變量之間的拼接使用佔位符的方式。
//:因爲 String 字符串的拼接會使用 StringBuilder 的 append()方式,有一定的性能損耗。使用佔位符僅是替換動作,可以有效提升性能
logger.debug("Processing trade with id: {} and symbol: {}", id, symbol);
  1. 對於 trace/debug/info 級別的日誌輸出,必須進行日誌級別的開關判斷。
  2. 避免重複打印日誌,浪費磁盤空間,務必在 log4j.xml 中設置 additivity=false。
<logger name="com.taobao.dubbo.config" additivity="false"> 
  1. 異常信息應該包括兩類信息:案發現場信息和異常堆棧信息。如果不處理,那麼通過關鍵字 throws 往上拋出。
logger.error(各類參數或者對象 toString() + "_" + e.getMessage(), e);
  1. 謹慎地記錄日誌。生產環境禁止輸出 debug 日誌;有選擇地輸出 info 日誌;如果使用 warn 來記錄剛上線時的業務行爲信息,一定要注意日誌輸出量的問題,避免把服務器磁盤撐爆,並記得及時刪除這些觀察日誌。
  2. 可以使用 warn 日誌級別來記錄用戶輸入參數錯誤的情況,避免用戶投訴時,無所適從。如非必要,請不要在此場景打出 error 級別,避免頻繁報警。
  3. 儘量用英文來描述日誌錯誤信息,如果日誌中的錯誤信息用英文描述不清楚的話使用中文描述即可,否則容易產生歧義。
  4. 【強制】國際化團隊或海外部署的服務器由於字符集問題,使用全英文來註釋和描述日誌錯誤信息
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章