-
Notifications
You must be signed in to change notification settings - Fork 45
securerandom slow
landon edited this page Sep 14, 2018
·
1 revision
-
现象:现在手机版本登录有一个现象,每次版本热更完毕后(游戏服务器重启),登录游戏服务器(外网阿里云)时要转菊花,转个10个秒才能进入游戏(第一次)
-
堆栈
"NioProcessor-2" #62 prio=5 os_prio=0 tid=0x000000000193a000 nid=0x224e runnable [0x00007f64e39fa000] java.lang.Thread.State: RUNNABLE at java.io.FileInputStream.readBytes(Native Method) at java.io.FileInputStream.read(FileInputStream.java:255) at sun.security.provider.SeedGenerator$URLSeedGenerator.getSeedBytes(SeedGenerator.java:539) at sun.security.provider.SeedGenerator.generateSeed(SeedGenerator.java:144) at sun.security.provider.SecureRandom$SeederHolder.<clinit>(SecureRandom.java:203) at sun.security.provider.SecureRandom.engineNextBytes(SecureRandom.java:221) - locked <0x0000000692f66dc8> (a sun.security.provider.SecureRandom) at java.security.SecureRandom.nextBytes(SecureRandom.java:468) - locked <0x0000000692f670e8> (a java.security.SecureRandom) at com.xx.net.mina.typical.security.AesAlgorithm.generateIv(AesAlgorithm.java:90) at com.xx.net.mina.typical.security.AesKeyConfig.<init>(AesKeyConfig.java:52) at com.xx.net.mina.typical.security.CryptoConfigFactory.create(CryptoConfigFactory.java:14) at com.xx.net.mina.typical.filters.SessionFilter.messageReceived(SessionFilter.java:97) at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:542)
-
原因分析
-
建立连接要走aes加密
-
aes加密算法要用到SecureRandom
这里的罪魁祸首是SecureRandom generateSeed()。它使用/dev/random生成种子。但是/dev/random是一个阻塞数字生成器,如果它没有足够的随机数据提供,它就一直等,这迫使JVM等待。键盘和鼠标输入以及磁盘活动可以产生所需的随机性或熵。但在一个服务器缺乏这样的活动,可能会出现问题。 随机数产生器会手机来自设备驱动器和其它源的环境噪声数据,并放入熵池中。产生器会评估熵池中的噪声数据的数量。当熵池为空时,这个噪声数据的收集是比较花时间的。这就意味着,Tomcat在生产环境中使用熵池时,会被阻塞较长的时间。
-
-
解决方案
- 启动参数带上 -Djava.security.egd=file:/dev/./urandom
- 在JVM环境中解决,修改 $JAVA_PATH/jre/lib/security/java.security 中改成 securerandom.source=file:/dev/urandom
- 最终确认方案2
- 需要和运维沟通 统一加入到Java项目的checklist
- 补充:即使跟运维反馈了,还是把参数放到启动shell里稳一点,万一他忘了呢,反正不冲突
-
什么是urandom
/dev/random的一个副本是/dev/urandom(“unblocked”,非阻塞的随机数发生器[4]),它会重复使用熵池中的数据以产生伪随机数据。这表示对/dev/urandom的读取操作不会产生阻塞,但其输出的熵可能小于/dev/random的。它可以作为生成较低强度密码的伪随机数生成器,不建议用于生成高强度长期密码
-
参考