一個在大廠作高級Java開發的程序猿
前端
關注微信公衆號:IT 老哥java
回覆:Java實戰項目視頻教程:便可獲取200G,27套實戰項目視頻教程程序員
回覆:Java 學習路線,便可獲取最新最全的一份學習路線圖web
回覆:Java 電子書,便可領取 13 本頂級程序員必讀書籍spring
回覆:Java 全套教程,便可領取:Java 基礎、Java web、JavaEE 所有的教程,包括 spring boot 等數據庫
回覆:簡歷模板,便可獲取 100 份精美簡歷api
你們應該都經歷過雙十一
吧,那個流量大的恐怖
吧,那個併發高的嚇人
吧。那麼在一個高併發的系統裏,有哪些點是影響系統性能的呢,今天咱們來說其中一個點:自定義異常
微信
首先給你們看一段JDK
的Throwable
源碼markdown
public synchronized Throwable fillInStackTrace() {
if (stackTrace != null ||
backtrace != null /* Out of protocol state */ ) {
fillInStackTrace(0);
stackTrace = UNASSIGNED_STACK;
}
return this;
}
複製代碼
上面這段JDK
的源碼就是拋出異常時會調用的方法,這段方法暴露出兩個問題併發
synchronized
修飾整個異常方法JVM
和線程
)這些是咱們自定義的、能夠預知的異常,拋出這種異常並不表示系統出了問題,而是正常業務邏輯上的須要,例如用戶名密碼錯誤、參數錯誤等。
每每是運行時異常,好比數據庫鏈接失敗、IO 失敗、空指針等,這種異常的產生多數表示系統存在問題,須要人工排查定位。
相信你們都接觸過異常,對於業務異常,咱們只須要簡單的知道一個描述問題的字符串便可,棧追蹤信息對咱們的意義並不大。而對於系統異常,追蹤信息纔是排查錯誤不可或缺的參考。
你們試想,若是前端傳的參數錯了,系統裏就拋出一個異常,那麼在雙十一的狀況下一秒鐘得拋出多少個異常呢?
建立普通 Java 對象 (CustomObject extends HashMap)
建立普通 Java 異常對象(CustomException extends Exception)
建立改進的 Java 業務異常對象 (CustomException extends Exception,覆寫 fillInStackTrace 方法,而且去掉同步)
(運行環境:xen 虛擬機,5.5G 內存,8 核;jdk1.6.0_18)
(10 個線程,建立 10000000 個對象所需時間)
45284 MS
205482 MS
16731 MS
你們能夠看到正常拋出 Exception 的和覆寫了 fillInStackTrace 的 Exception,性能差距了不少倍,若是高併發的系統裏,就像雪球同樣越滾越大。影響系統的併發量。
咱們來看看很是 NB 的kafka源碼
是如何優化的。
/* avoid the expensive and useless stack trace for api exceptions */
/* 翻譯:避免對api異常進行昂貴且無用的堆棧跟蹤 */
@Override
public Throwable fillInStackTrace() {
return this;
}
複製代碼
不少開源框架都是這樣處理,避免沒必要要的性能浪費。
什麼是匠人精神,就是將一件事情作到極致。優化永無止境,且行且珍惜。