SecureRandom為什么會造成堵塞,如何解決?


前情提要:公司新引入了sonar對代碼監測,由此根據sonar提出的建議修改了生成隨機數的Random類。

修改前:

1 Random random = new Random();
2 int num = random.nextInt(200);
3 System.out.println("生成隨機數num=" + num);

修改后:

 1 int num = 200;
 2 
 3 try {
 4   Random random = SecureRandom.getInstanceStrong();
 5   num = random.nextInt(200);
 6 } catch (Exception ex) {
 7   logger.error("生成隨機數失敗:" + ex.getMessage());
 8 }
 9 
10 System.out.println("生成隨機數num=" + num);

修改完之后,運行了大概1天還是2天,后面有人反饋調用失敗,實際是超時。

查詢后台發現:調用的接口執行時間都在1分鍾兩分鍾以上,每次都運行超時。打印的也都是num=200,隨機數每次都是200,這才懷疑可能是之前根據sonar建議改過造成的。

但是在windows的測試案例里跑,兩段代碼並沒有什么不一樣,執行效果都挺快。帶着試一試的心態修改了代碼,部署到Linux機器上,問題終於迎刃而解。

后面在網上查詢資料發現:(摘取其中的一段)

1 如果你的服務器在Linux操作系統上,這里的罪魁禍首是SecureRandom generateSeed()。
2 它使用/dev/random生成種子。但是/dev/random是一個阻塞數字生成器,如果它沒有足夠的隨機數據提供,它就一直等,這迫使JVM等待。
3 鍵盤和鼠標輸入以及磁盤活動可以產生所需的隨機性或熵。但在一個服務器缺乏這樣的活動,可能會出現問題。

有2種解決方案:
1. 在Tomcat環境中解決:
可以通過配置 JRE 使用非阻塞的 Entropy Source:
在 catalina.sh 中加入這么一行:-Djava.security.egd=file:/dev/./urandom 即可。

2. 在 JVM 環境中解決(本人使用此方法):
打開jdk安裝路徑 $JAVA_PATH/jre/lib/security/java.security 這個文件,找到下面的內容:
securerandom.source=file:/dev/random 替換成:securerandom.source=file:/dev/./urandom

// 以上引用自:http://www.manongjc.com/detail/18-lpszfgoaxerlvil.html
當然,除了以上2種解決方案外,你還可以不使用SecureRandom。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM