java程序连oracle数据库频繁出现Connection reset问题

java项目在启动的时候,卡在数据库连接阶段,并且频繁抛出以下错误:

Caused by: java.net.SocketException: Connection reset
 at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:1

根据oracle的说明,oracle jdbc在连接时需要一些随机数来加密session。在linux系统中,随机数的产生依赖于/dev/random以及/dev/urandom两个设备。

这两个设备的差异在于:/dev/random的random pool通过搜集键盘,鼠标,中断,磁盘操作等系统中断来产生随机数,因此在系统的中断数不足时,/dev/random设备会一直封锁,尝试读取的进程就会进入等待状态,直到系统的中断数充分够用, /dev/random设备可以保证数据的随机性,一般用于产生高随机性的公钥或一次性密码本。

而 /dev/urandom不依赖系统的中断,它会重复使用熵池中的数据以产生伪随机数据。这表示对/dev/urandom的读取操作不会产生阻塞,但是数据的随机性也不高,属于伪随机。

由于系统默认是使用/dev/random产生随机数,因此,当系统中断不足时,java程序连接oracle时便会一直等待,直到超时。侥幸的话,多尝试几次可以成功连接,而运气不好的话,只能通过重启操作系统来解决。
在内网环境下,随机性要求应该不是那么严格,我们可以采用/dev/urandom来产生随机数的方法来提高程序连接,最简便的方法是将random替换为urandom
mv /dev/random /dev/random-bak

ln -s /dev/urandom /dev/random
之后再重启应用的时候,极少出现连接被reset的情况,且程序初始化的速度大大提升。