我有一个新的tomcat应用服务器在tomcat 6,java 6(openjdk),centos 6.2上运行 . 服务器是在centos 6.2主机上的qemu-kvm下运行的虚拟机 . 主机和客户端都是64位 .
我有一个连接打开的情况(从连接池)然后“长计算”发生约4小时,在此期间不使用连接 . 最后,发出“commit”,服务器给出“连接重置”异常,具体为:
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 回答
@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
业务用户,安全团队或架构师经常建议网络/操作系统管理员使用防火墙和路由器中止空闲连接 . 这在反黑客社区中始终是一个“推荐”,但它没有得到适当的讨论,并导致应用程序不稳定 . 最后,您应该与团队讨论以找到 balancer 点
正如您在Oracle论坛的this帖子中所看到的,这可能有多个问题/解决方案 .
检查JDBC驱动程序版本是否正确
检查您的ORACLE_HOME环境变量
尝试添加参数
-Djava.security.egd=file:///dev/urandom
您的逻辑使用单例来获取连接?在帖子中也提到了这一点
希望这对你有所帮助 .
我已经遇到过这种情况了 . 几乎总是由网络超时(负载均衡器或防火墙)引起 . 但是你已经明确提到你的服务器在同一个子网上,所以不确定是怎么回事 . 既然你怀疑iptables,你可以把它关闭,运行测试,看看它是否有效(太容易了吧):)
无论如何,假设您正在连接到Oracle数据库,以下调整会有所帮助
http://raibledesigns.com/rd/entry/tomcat_oracle_connectivity_problems
如果使用不同的db(比如mysql),设置可能会有所不同,但逻辑是相同的 . 设置keepalive值以防止连接空闲时间过长 . 这样firewal / load balancer / iptables软件就不会终止它 .