记录一次解决使用jdbc创建oracle连接慢的问题

在测试环境出现了这样一个问题:有几个任务执行的时候(由调度执行,频次10分钟一次),偶尔会出现创建oracle连接慢的问题(大概几十秒到几分钟)。问题的定位是通过打日志,在DriverManager.getconnection()的上面和下面各打一行日志,发现如果出现慢的时候,都是在创建连接的时候卡住了。

于是去看DriverManager的源码,发现Drivermanager其实是有日志打印的,只不过需要用户特意指定一下,通过下面的代码,就可以让DriverManager打印日志:

DriverManager.setLogWriter(new PrintWriter(System.out) {
            @Override
            public void println(String x) {
                // 给日志附加时间戳
                x = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()) + " " + x;
                super.println(x);
            }
        });

这段代码需要在调用DriverManager.getConnection()之前调用。通过日志的输出,我们能很容易发现DriverManager的spi机制,每次创建连接的时候,是从一个list中遍历尝试,看哪个驱动支持这个url;而且驱动可以通过spi加载,并不用手动执行类似这样的代码去注册:

Class.forName("xxxxx");

增加日志以后,等待测试环境再次出现这个问题的时候,发现出现类似下面的日志(时间久了,只找了一个类似的日志):

at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:428)
at oracle.jdbc.driver.PhysicalConnection.(PhysicalConnection.java:536)
at oracle.jdbc.driver.T4CConnection.(T4CConnection.java:228)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:521)
at java.sql.DriverManager.getConnection(DriverManager.java:582)
at java.sql.DriverManager.getConnection(DriverManager.java:185)

实际上我们每次获取的连接,都是失败以后重试获取的,如果不加deriverManager很可能会看不到。网上搜索这个日志,发现这是一个oracle优化的功能,使用本地的一个算法进行的优化,直接给出修改方案:

解决方法:
$JAVA_HOME/jre/lib/security 目录下 java.security 文件:
securerandom.source=file:/dev/../dev/urandom

有些人可能会说了,"file:/dev/../dev/urandom"不就是"file:/dev/urandom"嘛?实际上并不一定,可能有的代码里分析了这个字符串,从我们环境实测情况发现改成后者,没效果。。

你可能感兴趣的:(JAVA,sql,oracle,java)