Oracle 12c 在使用客户端连接数据库,或者 java 应用程序在连接数据库时,时慢时快,如果应用设置了连接超时,就可能触发连接超时报错。这个问题在"1594701.1"中有相关的解释。
1594701.1: JDBC connection establishment with 11.2.x databases uses a new connection mechanism (o5logon) that requires the use of random numbers. These numbers are typically generated by a special device (/dev/random). However, this random number generator relies on entropy in order to generate sufficiently random numbers. This entropy comes from things like mouse pointer movement and keyboard entry. When there is insufficient entropy, the random number generator will not return any numbers. When this happens, the o5logon used by the JDBC library stalls, and has to wait until sufficient entropy is available. To address this issue, /dev/urandom is used instead. This device does not block, so JDBC connection establishment is not delayed.
在Linux系统中,/dev/random和/dev/urandom 是两个特殊的设备文件,用于生成随机数。
/dev/random
/dev/random是一个随机数生成器设备文件,用于生成高质量的随机数。它通过收集系统上的环境噪声(例如硬件噪声,磁盘活动等)来产生随机数。由于它只在系统上有足够的环境噪声时才能生成随机数,因此/dev/random 生成的随机数是高质量的。
但是,/dev/random的主要缺点是,如果系统上的环境噪声不足,则会导致生成随机数的速度变慢,有时甚至会完全停止。这可能会导致某些应用程序无法正常工作,因为它们需要大量的随机数。
/dev/urandom
与/dev/random不同,/dev/urandom是一个伪随机数生成器设备文件,它通过使用内部熵池来生成随机数。它会持续生成随机数,无论系统上的环境噪声有多少。因此,/dev/urandom生成的随机数速度比/dev/random快得多。
由于/dev/urandom使用的是伪随机数生成算法,因此在某些情况下,可能会产生较低质量的随机数。例如,在系统启动时,内部熵池可能不够大,因此生成的随机数可能不够随机。但是,在系统运行一段时间后,熵池会变得更大,并且生成的随机数的质量也会提高。此外,Linux内核2.6.12+(2005年发布)起,/dev/urandom 已采用密码学安全的重播种机制,只要初始熵够(启动时一次),后续输出就是加密安全的。
如何使用 /dev/random 和 /dev/urandom
在Linux系统中,可以通过读取 /dev/random 或 /dev/urandom 来获取随机数。
例如,以下命令将生成10个随机字节并将它们输出到标准输出:
$ head -c 10 /dev/random
类似地,以下命令将生成10个伪随机字节并将它们输出到标准输出:
$ head -c 10 /dev/urandom
请注意,这些命令将生成二进制随机数据。如果您需要生成可读的随机数据,请使用以下命令:
$ head -c 10 /dev/random | base64
$ head -c 10 /dev/urandom | base64
这将生成10个随机字节并将它们转换为Base64编码,以便更容易阅读和使用。
如何选择 /dev/random 和 /dev/urandom
在Linux系统中,/dev/random 和 /dev/urandom 是用于生成随机数的特殊文件。
/dev/random 和 /dev/urandom 都使用熵池来生成随机数,但它们的行为方式有所不同。
/dev/random 会在熵池中的熵低于一定值时阻塞等待熵的增加。
而 /dev/urandom 不会阻塞等待熵,而是使用伪随机数生成器来生成随机数。
在选择 /dev/random 或 /dev/urandom 时,需要权衡随机数的安全性和性能。
一般来说,对于需要高安全性的场景,建议使用 /dev/random;
对于需要高性能的场景,建议使用 /dev/urandom。
但是,实际上,大多数情况下,/dev/urandom 的安全性也足够,并且速度更快。
如何强制使用 /dev/urandom
方法1:JVM启动参数强制指定 SecureRandom 算法
加 -Djava.security.egd=file:/dev/./urandom 注意/dev/./urandom这个写法,它绕过OpenJDK某些版本校验的惯用技巧
方法2:修改 $JAVA_HOME/jre/lib/security/java.security
把 securerandom.source=file:/dev/random 改成 file:/dev/urandom 但容器环境常不可写,且多实例共用JRE时有风险
方法3:代码里显式构造 SecureRandom
比如 new SecureRandom(new byte[20]) 或 SecureRandom.getInstance("SHA1PRNG") 但数据库驱动内部仍可能走默认路径,治标不治本
方法4:mv /dev/random /dev/random.old; ln /dev/urandom /dev/random; ll /dev/*ran*