異常處理機制漫談 什麼是異常處理機制 異常處理機制構成 異常處理原則 try-catch異常捕獲的侷限 對異常處理機制的期待 如何自定義異常處理機制 小結

什麼是異常處理機制

    異常處理機制是處理系統非正常運行的流程
    系統在運行時候,會出現因子系統實現錯誤、外界非法輸入、環境引發硬件故障等因素造成的偏離正常執行流程的情況。異常處理機制考慮的就是當這些異常情況出現的時候,如何處理能夠使能損失降到最低。

異常處理機制構成

    1 異常檢測
    2 異常拋出;
    3 異常捕獲;
    4 異常處理。
    用僞代碼示例把他們結合起來就是

// try代碼塊開始的地方就是異常捕獲的開始位置
// try代碼塊結束的地方就是異常捕獲的結束位置
try{
  if(檢測到異常){
    throw  new Exception("異常信息")
  }
}catch(Exception e){
    if(需要處理異常){
       處理異常
   }else{
       // 不處理,並且拋給try開始的這段代碼被調用的方法處理
       throw e
  }
}

雖然簡單,但是所有異常處理機制莫不如此構建。

異常處理原則

    1 內部能處理的自己處理;
    2 內部處理不了的丟給調用者;
    3 每層系統都設置全局異常處理者。

try-catch異常捕獲的侷限

     1 不能跨線程捕獲異常;
     每個包含try catch的方法都有一個Exception tab,Exception tab裏面每一條exception 定義了一個Exception的可能發生起始位置,Exception類型,如果匹配成功去哪一行開始執行。當拋出異常後,虛擬機便從當前方法的異常表進行異常匹配,如果匹配成功則進行異常處理,如果匹配不成功則去該方法的調用地方(也是一個方法)去匹配異常表,如何找到該方法的調用方法呢,其實就是利用了線程的方法棧,先調用的方法先入棧,後調用的後入棧,以此類推直到線程的方法棧爲空爲止。由於每個線程是有唯一的棧,所以當處於不同線程時候,被調用方法進行異常匹配時候便找不到調用它的方法,所以不能跨線程捕獲異常, java、 c++、 js都是如此。
     2 不能跨語言捕獲異常
     不同的語言採用的方法棧不是一個棧,比如Android中有java棧-虛擬機棧,C棧-本地方法棧,當在java層用try catch捕獲異常,如果在try代碼塊中調用的native方法出現了異常,java層是無感知的,需要額外在c++層進行捕獲,這也是每層系統都需要自己的全局異常處理的原因之一。

對異常處理機制的期待

     1 對未捕獲的異常有自己處理方式
     2 支持線上用戶異常的感知與分析
     3 對整個系統來說有統一的異常處理機制

如何自定義異常處理機制

1 找到替換本層系統全局異常處理器的方案;
2 自定義異常處理方法處理已知異常;
3 添加定位異常需要的額外信息,重新組合後再拋給APM平臺。
Demo:https://github.com/kingkong-li/AwesomeProject

小結

    一個好的異常處理機制就是當異常出現的時候,能將損失降到儘可能低,並能以儘量低的成本去定位線上問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章