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