SQLRecoverableException:I/O异常:连接重置

Mai*_*aik 18 java oracle ioexception connection-reset

昨天晚上,我离开了办公室,运行了一个由我编写的Java程序.它应该使用JDBC连接将大量记录插入到我们的公司数据库(Oracle)中.今天早上当我回来工作时,我看到了这个错误(由try-catch捕获):

java.sql.SQLRecoverableException: I/O Exception: Connection reset
Run Code Online (Sandbox Code Playgroud)

在得到这个问题之前,该程序几乎写了所有记录,但如果它发生得很早(我晚上离开办公室几分钟后)怎么办?我无法理解发生了什么,我联系了我的数据库管理员,他说数据库没有特别的问题.

关于发生了什么以及我可以做些什么来避免它的任何想法?

小智 26

某些RedHat发行版上发生错误.您需要做的唯一事情是使用参数java.security.egd = file:/// dev/urandom运行您的应用程序:

java -Djava.security.egd=file:///dev/urandom [your command]
Run Code Online (Sandbox Code Playgroud)

  • 我绞尽脑汁想弄清楚这个问题三天了,你的解决方案终于解决了这个问题。这是多么离谱的问题啊!!此外,要获得更深入的答案,请查看 https://discuss.pivotal.io/hc/en-us/articles/230141007-Java-Web-Applications-Slow-Startup-or-Failing (3认同)
  • 3天 ?在这里已经两个月了,非常感谢!(我猜 OpenStack 熵吞吐量比 VMware 低得多) (3认同)

tda*_*get 17

我想为nacho-soriano的解决方案提供一个补充的答案......

我最近搜索解决了Java编写的应用程序(实际上是Talend ELT作业)想要连接到Oracle数据库(11g及以上)然后随机失败的问题.操作系统是RedHat Enterprise和CentOS.工作非常安静(不超过半分钟)并且经常发生(每5分钟大约运行一次).

有时候,在夜间作为工作时间,在数据库密集型工作使用期间作为懒惰的工作使用,只需一个字随机,连接失败并显示以下消息:

Exception in component tOracleConnection_1
java.sql.SQLRecoverableException: Io exception: Connection reset
        at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:101)
        at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:112)
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:173)
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:229)
        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:458)
        at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:411)
        at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:490)
        at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:202)
        at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:33)
        at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:465)
        at java.sql.DriverManager.getConnection(DriverManager.java:664)
        at java.sql.DriverManager.getConnection(DriverManager.java:208)
    and StackTrace follow ...
Run Code Online (Sandbox Code Playgroud)

问题解释:

详情见这里

Oracle连接需要一些随机数来承担良好的安全级别.Linux随机数生成器生成一些基于键盘和鼠标活动的数字(以及其他)并将它们放在堆栈中.您将在服务器上授予我不存在大量此类活动的权限.因此,软件使用比发生器可以产生的更多随机数.

当池为空时,从/ dev/random读取将阻塞,直到收集到额外的环境噪声.并且Oracle连接属于超时(默认为60秒).

解决方案1 ​​ - 针对一个应用解决方案

解决方案是在启动时添加两个给JVM的参数:

-Djava.security.egd=file:/dev/./urandom
-Dsecurerandom.source=file:/dev/./urandom
Run Code Online (Sandbox Code Playgroud)

注意: '/./'很重要,不要掉线!

所以启动命令行可以是:

java -Djava.security.egd=file:/dev/./urandom -Dsecurerandom.source=file:/dev/./urandom -cp <classpath directives> appMainClass <app options and parameters>
Run Code Online (Sandbox Code Playgroud)

该解决方案的一个缺点是随着随机性的影响,生成的数字不太安全.如果您不在军事或秘密相关行业工作,这个解决方案可能是您的.

解决方案2 - 通用Java JVM解决方案

正如解释这里

解决方案1中给出的两个指令都可以放在Java安全设置文件中.

看一眼 $JAVA_HOME/jre/lib/security/java.security

改变线

securerandom.source=file:/dev/random
Run Code Online (Sandbox Code Playgroud)

securerandom.source=file:/dev/urandom
Run Code Online (Sandbox Code Playgroud)

对于新运行的应用程序,更改立即生效.

对于解决方案#1,该解决方案的一个缺点是随着随机性的影响,生成的数字不太安全.这一次,它是全球JVM的影响.至于解决方案#1,如果你不在军事或秘密相关行业工作,这个解决方案可以是你的.

解决方案3 - 硬件解决方案

免责声明:我没有链接任何硬件供应商或产品......

如果您需要达到高质量的随机性级别,您可以通过一个硬件替换Linux随机数生成器软件.

这里提供一些信息.

问候

托马斯

  • 我只是想了一下,**解决方案 #4** 可能是直接在数据库服务器配置上延长超时时间以超过 60 秒的限制。&lt;br&gt;在 sqlnet.ora 和 tnsnames.ora Oracle 的监听器配置文件中,您可以考虑`TCP.CONNECT_TIMEOUT`和`SQLNET.OUTBOUND_CONNECT_TIMEOUT`参数。 (2认同)

ken*_*ohn 14

这只是意味着后端(DBMS)中的某些东西由于资源不可用而决定停止工作等.它与您的代码或插入数量无关.您可以在此处阅读有关类似问题的更多信

这可能无法回答您的问题,但您会了解为什么会发生这种情况.您可以与您的DBA进一步讨论,看看您的案例中是否有特定的内容.


Liz*_*Liz 5

在从 11g 升级到 12c 并且我们的 java 是 1.6 之后,我们间歇性地遇到了这些错误。

我们的修复是将 java 和 jdbc 从 6 升级到 7

export JAVA_HOME='/usr/java1.7'

export CLASSPATH=/u01/app/oracle/product/12.1.0/dbhome_1/jdbc/libojdbc7.jar:$CLASSPATH 
Run Code Online (Sandbox Code Playgroud)

几天后,仍然间歇性的连接重置。

我们最终删除了上面所有的 java 7。Java 6 很好。通过将其添加到我们的用户 bash_profile 来解决问题。

我们遇到错误的 groovy 脚本在我们的批处理 VM 服务器上使用 /dev/random。下面强制 java 和 groovy 使用 /dev/urandom。

导出 JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:///dev/urandom"


use*_*907 5

解决方案
更改应用程序的设置,因此java命令旁边的参数[ -Djava.security.egd = file:/ dev /../ dev/urandom ]:

java -Djava.security.egd = file:/ dev /../ dev/urandom [你的命令]

参考: - https://community.oracle.com/thread/943911