oracle瘦jdbc连接在不活动后接收“连接重置”

问题描述:

我有一个运行在tomcat 6,java 6(openjdk),centos 6.2上的新的tomcat应用服务器。该服务器是在centos 6.2主机上运行在qemu-kvm下的虚拟机。主机和来宾都是64位的。oracle瘦jdbc连接在不活动后接收“连接重置”

我有一个连接打开的情况(从连接池),然后“长时间计算”发生了大约4个小时,在此期间不使用连接。最后,“提交”被发出,并且服务器对“连接重置”的例外,具体如下:

Caused by: java.net.SocketException: Connection reset 
    at java.net.SocketInputStream.read(SocketInputStream.java:185) 
    at oracle.net.ns.Packet.receive(Packet.java:282) 
    at oracle.net.ns.DataPacket.receive(DataPacket.java:103) 
    at oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:230) 
    at oracle.net.ns.NetInputStream.read(NetInputStream.java:175) 
    at oracle.net.ns.NetInputStream.read(NetInputStream.java:100) 
    at oracle.net.ns.NetInputStream.read(NetInputStream.java:85) 
    at oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:122) 
    at oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:78) 
    at oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1179) 
    at oracle.jdbc.driver.T4CMAREngine.unmarshalSB1(T4CMAREngine.java:1155) 
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:279) 
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186) 
    at oracle.jdbc.driver.T4C7Ocommoncall.doOCOMMIT(T4C7Ocommoncall.java:75) 
    at oracle.jdbc.driver.T4CConnection.doCommit(T4CConnection.java:558) 

数据库服务器和客户端在同一个子网中,除了服务器是一个真正的物理主机,很明显,应用程序服务器是在同一子网上的物理机器中运行的客户机。

主机使用“桥接”网络。

这可能不是软件问题,而是linux os配置(iptables?)问题,但我真的不知道。

我碰到过这个问题。几乎总是由网络超时(负载均衡器或防火墙)造成的。但是你已经明确提到你的服务器在同一个子网上,所以不确定发生了什么。既然你怀疑iptables的,你可以将其关闭,运行测试,看看它是否工作(太容易了吧:)

无论如何,假设你连接到Oracle数据库,下面的调整有助于

http://raibledesigns.com/rd/entry/tomcat_oracle_connectivity_problems

如果你使用不同的数据库(比如说mysql),设置可能会不同,但逻辑是一样的。设置Keepalive值以防止连接闲置太久。这样,防火墙/负载均衡器/ iptables软件将不会终止它。

+0

我相信这个问题是由做一个“system-config-firewall-tui”导致的,它间接刷新了iptables的配置和重新加载。这会导致一些现有连接死亡。 – dmansfield 2012-02-15 22:16:18

正如您在Oracle论坛中发布的this文章中所看到的,这可能有多个问题/解决方案。

  • 检查您的JDBC驱动程序版本是正确的
  • 检查ORACLE_HOME环境变量
  • 尝试添加参数-Djava.security.egd=file:///dev/urandom
  • 你的逻辑使用单获取连接?在帖子中也提到了这个

希望这可以帮助你。

+0

当我读它时,/ dev/urandom修复用于连接超时。这是连接的,有效的,用于某些语句,然后闲置。它仍然有可能成为/ dev/urandom修复程序? – dmansfield 2012-02-10 18:18:00

+0

对不起,赶快输入。至于ORACLE_HOME和其他sqlnet.ora调整,我不认为它们适用于我使用的** thin **驱动程序(未指定)。但我会检查驱动程序的版本。 – dmansfield 2012-02-10 18:20:00

@user通过在sqlnet.ora中配置“SQLNET.EXPIRE_TIME = 10”引用了一个很好的解决方法。

但是,此解决方法仅适用于您的应用程序使用厚OCI(jdbc:oci)而不是瘦(jdbc:thin)驱动程序。

Linux有软件防火墙,即iptables,它可以挂起空闲的网络连接,所以即使你在同一个子网中,你也可以使用iptables软件防火墙。这在所有现代Linux中都是默认激活的,直到Linux管理员禁用它。

默认情况下,Linux iptables不会丢失空闲TCP/IP连接(jdbc属于TCP/IP协议),所以Linux管理员必须配置iptables才能这样做。以下是任何读者谁有兴趣了解更多的详细的解释:

http://www.digitage.co.uk/digitage/software/linux-security/cutter

企业用户,安全团队,或者建筑师常提示网络/ OS管理员使用防火墙来终止空闲连接,以及路由器。这总是反黑客社区的“推荐”,但它没有得到适当的讨论,并导致应用程序不稳定。最后,你应该与团队讨论找到一个余额