[轉帖]JFR 定位因爲 SSL 導致 CPU Load 飈高的問題

https://juejin.cn/post/6877132677854527495

 

 
專欄: 
Java JFR全解
 

問題場景

在某一時刻,某個微服務的某個實例 CPU 負載突然飈高:

image

同時建立了很多數據庫鏈接: image

其他實例沒有這個現象。

問題定位

由於建立了很多數據庫鏈接,猜想可能是數據庫比較慢,查看數據庫這段時間的 SQL 統計,發現數據庫並不慢:

image

其中這個微服務這段時間的熱點 SQL,執行並不慢。那麼問題出在了哪裏呢?可能是由於 GC,可能是由於 safepoint,還有可能是獲取鎖時間過長(參考:Java 監控 JFR全解),我們 dump 一下 JFR 並查看其中的 safepoint,GC 以及 Monitor Blocked 相關事件。

首先查看GC,發現都是 Young GC, GC 暫停時間也可以接受。

image

然後是 safepoint,雖然有采集到 safepoint,但是暫停時間也沒有很長。

image

最後查看 Java Monitor Block,發現有很多很長時間的鎖等待:

image

堆棧顯示,阻塞在:void sun.security.provider.SecureRandom.engineNextBytes(byte[])上面,這就是一個經典的問題,Java Random,參考代碼:NativePRNG

 
arduino
複製代碼
// name of the *System* property, takes precedence over PROP_RNDSOURCE
private static final String PROP_EGD = "java.security.egd";
// name of the *Security* property
private static final String PROP_RNDSOURCE = "securerandom.source";

private static final boolean useLegacyDSA =
    Boolean.parseBoolean(GetPropertyAction.privilegedGetProperty
        ("jdk.security.legacyDSAKeyPairGenerator"));

static final String URL_DEV_RANDOM = "file:/dev/random";
static final String URL_DEV_URANDOM = "file:/dev/urandom";

涉及到兩種隨機數 seed 生成方式,一種是"file:/dev/random",另一種是"file:/dev/urandom",通過設置系統屬性java.security.egd指定,默認是"file:/dev/random"

兩種 Random 原理與解決

在 Linux 4.8 之前:

image

在 Linux 4.8 之後:

image

在熵池不夠用的時候,默認的"file:/dev/random"會阻塞,"file:/dev/urandom"不會,繼續用。對於我們來說,"file:/dev/urandom"夠用,所以通過-Djava.security.egd=file:/dev/./urandom設置系統屬性,使用 urandom 來減少阻塞。

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