oracle thin jdbc连接接收"连接重置"不活动后

时间:2012-02-08 22:54:46

标签: linux oracle tomcat jdbc connection-pooling

我有一个新的tomcat应用服务器在tomcat 6,java 6(openjdk),centos 6.2上运行。该服务器是在centos 6.2主机上的qemu-kvm下运行的虚拟机。主机和来宾都是64位。

我有一个连接打开的情况,(从连接池)然后是一个"长计算"发生约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)

数据库服务器和客户端位于同一子网上,但服务器是真正的物理主机,显然app-server是在同一子网上的物理机器内运行的guest虚拟机。

使用的主机"桥接"联网。

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

3 个答案:

答案 0 :(得分:1)

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

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

希望这会对你有所帮助。

答案 1 :(得分:1)

我遇到过这种情况。几乎总是由网络超时(负载均衡器或防火墙)引起的。但是你已经明确提到你的服务器在同一个子网上,所以不确定发生了什么。既然您怀疑iptables,可以关闭它,运行测试,看它是否有效(太简单了吧)

无论如何,假设您正在连接到Oracle数据库,以下调整有助于

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

如果使用不同的db(比如mysql),设置可能会有所不同,但逻辑是相同的。设置keepalive值以防止连接空闲时间过长。这样firewal / load balancer / iptables软件就不会终止它。

答案 2 :(得分:1)

@user指的是一个很好的解决方法,通过配置" SQLNET.EXPIRE_TIME = 10"在sqlnet.ora中。

但是,此解决方法仅适用于您的应用程序使用的是厚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

业务用户,安全团队或架构师经常建议网络/操作系统管理员使用防火墙以及路由器中止空闲连接。这始终是一个推荐"在反黑客社区,但它没有得到适当的讨论,并导致应用程序不稳定。最后,您应该与团队讨论以找到平衡