Linux环境下java程序获取oracle数据库连接超时的问题解决

Linux下运行java程序(jdk 1.7),该程序会获取Oracle数据库连接,为了提高处理速度,采用了多个进程并行启动处理,这时,偶尔会发生数据库连接获取超时失败的异常发生.而且windows环境下没有问题.

java.sql.SQLException: IO Error: End of TNS data channel
 at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:458)
 at oracle.jdbc.driver.PhysicalConnection.(PhysicalConnection.java:546)
 at oracle.jdbc.driver.T4CConnection.(T4CConnection.java:236)
 at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)


或者

java.sql.SQLException: IO Error: Connection reset
 at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:467)
 at oracle.jdbc.driver.PhysicalConnection.(PhysicalConnection.java:546)
 at oracle.jdbc.driver.T4CConnection.(T4CConnection.java:236)
 at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)

解决办法:

       java启动的时候添加启动参数 「-Djava.security.egd=file:/dev/./urandom」

注意:「-Djava.security.egd=file:/dev/urandom」的话,相当于「-Djava.security.egd=file:/dev/random」

原因分析

       Oracle的JDBC  driver程序里面在获取db连接的时候用到了java的SecureRandom,来获取随机字节数据流,用来产生随机数,-Djava.security.egd配置的就是随机数据收集伪设备,linux下有两种:

       1./dev/random,利用系统中断来生成随机数据,所以当系统不是很繁忙的时候,中断数很少,那么调用进程就会进入等待状态,直到有足够用的中断数的时候,才会返回随机数,而这时可能已经发生getConnection超时了

       2./dev/urandom,不利用系统中断来生成随机数,所以不会造成调用进程等待

扫描二维码关注公众号,回复: 238366 查看本文章

所以,我们的遇到的情况必须使用urandom才行,由于java的bug,即使指定file:/dev/urandom,SecureRandom使用的仍然是random,为了绕过这个bug,我们发现了「-Djava.security.egd=file:/dev/./urandom」这种配置方式,来达到我们使用urandom的目的.

 为了验证配置前后的速度,可以用下面的小程序进行对比确认

JRand.java

import java.security.SecureRandom;
class JRand {
    public static void main(String args[]) throws Exception {
        System.out.println("Ok: " +
            SecureRandom.getInstance("SHA1PRNG").nextLong());
    }
}



time java -Djava.security.egd=file:/dev/urandom  JRand

time java -Djava.security.egd=file:/dev/./urandom  JRand

猜你喜欢

转载自blogzhoubo.iteye.com/blog/2358653