Skip to main content

錯誤處理 - 策略和機制

錯誤處理策略

  • 向上拋出
    • 在某個入口統一處理錯誤,提高程式碼復用和可讀性
  • 捕獲並處理
    • 對於發生預期內的錯誤,且我們有足夠的處理條件,應該直接處理,不需要層層拋出,避免不必要的訊息
  • 回饋用戶
    • 用戶操作錯誤的資訊,系統要及時回饋修正錯誤
  • 重試
    • 有時從遠程服務獲取數據,可能出現錯誤。這種情況下,可以考慮採取重試策略,但要設置重試次數和重試時間間隔,避免資源服務器不必要的壓力。
  • 錯誤日誌
    • 某些錯誤不需要用戶知道,我們需要記錄他用作日後系統運作觀察和修復,錯誤日誌中添加告警機制。

異常處理機制

  • try-catch
    • 常見的錯誤捕獲方式,在 try 區塊中可能拋出錯誤,在 catch 區塊中處理錯誤。(此種機制只能捕獲同步程式碼的錯誤)
  • callback 函數
    • 通常第一個參數作為錯誤傳遞,如果有錯誤即處理,否則繼續下一步
  • promise
    • 使用 catch 來捕獲錯誤處理
  • EventEmitter
    • EventEmitter 提供 error 事件來處理錯誤,當錯誤發生時,EventEmitter 觸發 error 事件,並將錯誤參數傳給 error 事件的處理函數
async function errorHandler (ctx, next) {
try {
await next ();
} catch (error) {
let status = error.status || 500;
let message = 'internal server error';
ctx.body = { status, message };
}
}

調試工具

  • node - inspect
    • 使用 inspect 模式,開啟一個進程監聽調試請求,默認監聽端口 9229 ,每個監聽進程被分配唯一UUID,調試客戶端通過 ws://{host}:{port}/{UUID} 和監聽進程建立 websocket 通信。想要開啟調試器我們需要在程式碼加入 debugger 標籤,當 nodejs 運行到 debugger 標籤時自動暫停
  • chrome devtools
    • chrome devtools 根據 V8 引擎的調試協議向 nodejs 進程發送指令,控制程式碼運行
  • VSCode
    • launch:開啟 debug 模式
    • attach:將 debugger 連接運行中的程序

線上異常定位

https://blog.csdn.net/qq_42880714/article/details/133327149

  • 發現問題:最好在用戶發現問題前,自己發現問題,可以透過線上異常監控和日誌
    • 監控性能指標(CPU、記憶體、硬碟空間等等),應用程序指標(QPS、請求響應時間、錯誤率)
  • 快速反應:一旦發現問題快速反應,即使當下不了解問題原因,但要先解決問題,進行版本回滾或快速修復
    • 版本回滾、服務降級、切換備份、限流或降速
  • 定位解決:一旦問題得到解決,我們需要深入分析服務、程式碼和數據找到根本原因
    • 使用日誌服務,收集報錯訊息、用戶反饋等問題,協助分析和定位問題
    • 關鍵數據:trace、error stack、出入参、ip、time
    • 通過鏈路追蹤系統整個請求路徑,分析函數之間的調用關係

性能排查

  • 內存洩漏
    • NodeJS 的總內存佔用曲線長時間只增不降,堆內存超過堆限制60-70%,很大可能產生內存洩漏
    • 排除方式 heapdump:在分析 heapdump 數據時,可以檢視兩個指標 "Shallow Size"和"Retainde Size","Shallow Size" 是 V8 堆在對象自身創建時分配的大小,而"Retainde Size"表示對象在從堆中移除後、並在進行 Full GC 後釋放的空間大小。通常在內存泄漏情況下,"Retainde Size"會非常大。
  • CPU 告警
    • 可能原因 Full GC、IO 操作、死循環、大量計算
    • 排除方式 導出 cpu profile 文件,使用 chrome 工具查看,檢視兩種視圖 Heavy 視圖和 Chart 視圖,火焰圖頂層函數佔用寬度,出現平頂,說明該函數出現性能問題
  • 硬盤佔用率
    • 高流量場景記錄大量日誌,QPS請求量大時,沒有定時清理日誌,導致硬盤佔用空間增大