問題起因
一個對外提供的接口,中間需要調用第三方接口,涉及到三方機密問題,其中使用到了安全隨機數
之前的寫法如下
public static String randomCode() {
Random r = new Random();
StringBuilder str = new StringBuilder();
for (int i=0;i<6;i++){
str.append((r.nextInt(10)));
}
return str.toString();
}
被solar掃面到不符合規範於是就改成下面的:
public class CodeUtil {
private CodeUtil() {}
// SecureRandom is preferred to Random
private static Random rand;
static {
try {
rand = SecureRandom.getInstanceStrong();
} catch (NoSuchAlgorithmException e) {
log.error("NoSuchAlgorithmException: {}", e);
}
}
public static String randomCode() {
StringBuilder str = new StringBuilder();
for (int i=0;i<6;i++){
str.append((rand.nextInt(10)));
}
return str.toString();
}
}
bug現象
之前所有調用對外暴漏的服務的時候都是正常的,第二天莫名其妙的報錯
根據這個報錯很自然就是想到服務調用超時,於是各種設置feign調用超時時間,但是都沒有起到效果,本地測試服務調用時間,發現時間開銷也並不是很高,總是感覺客戶端鏈接一到服務端就斷開了,於是估計因該是服務端的問題,但是本地調用也沒有問題,甚至在服務中sleep了30s,依然沒有顯示超時,排查了一個下午,也沒有搞明白到底是什麼錯誤
曙光
當時也不知道是什麼力量讓我在服務器上打出了一個top命令,發現了一個叫java的進程,pid爲1,於是就jstack了一下,驚喜的返現下面這些懂
仔細觀察了一下發現所有的http線程都阻塞在了同一把鎖上面,這個時候問題基本已經定位到了
於是還原了一下源代碼,問題成功解決
SecureRandom存在哪些問題
百度了一些文章
偶遇 JDK 1.8 還未修復的 SecureRandom.getInstance(“SHA1PRNG”) 之 bug