oracle 和c3p0 数据库的Time_Wait 过多问题的一个解决方案。

时间:2023-03-09 04:08:38
oracle 和c3p0 数据库的Time_Wait 过多问题的一个解决方案。

项目是B/S模式,放在linux服务器上,tomcat和oracle11g在一台服务器上,tomcat读取数据库采用C3P0连接池,一直比较稳定,所以也没有去管。后来把tomcat放在一台win2008下,数据库放在另外一台win2008下。运行了半月有余,期间经常报数据库连接错误,但刷新下页面也就好了。因为是偶发问题,也没有去关注。终于有一天彻底报错进不了了,报错截图如下:

oracle 和c3p0 数据库的Time_Wait 过多问题的一个解决方案。

oracle 和c3p0 数据库的Time_Wait 过多问题的一个解决方案。oracle 和c3p0 数据库的Time_Wait 过多问题的一个解决方案。

oracle 和c3p0 数据库的Time_Wait 过多问题的一个解决方案。

大意是与数据库连接有问题。这才慌慌的打开数据库服务器查看原因。数据库貌似正常,但用sqlplus连接不上,报超过最大连接数。于是用netstat -ano ,本意是想看看监听端口是否正常监听。未曾想出现了四百多条 1521端口 的time_wait信息:

oracle 和c3p0 数据库的Time_Wait 过多问题的一个解决方案。

难怪数据库连不上,于是就暂时先把数据库重启了下。查看了半个小时,数据库连接保持在50左右,以为正常了。到了下午,放心不下,又上服务器查看了一下,乖乖,又有200多条TIME_WAIT。还好发现的早,不然过几天肯定又得出问题。遂谷歌百度搜索一阵,貌似这个问题国内外出现不少,按照一个简单的解决方法:

在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters,添加名为TcpTimedWaitDelay的
DWORD键,设置为60,以缩短TIME_WAIT的等待时间 同时添加 MaxUserPort 值为 65534

之后一直就没再出现过这个问题。我就一直纳闷了,配置都差不多,难道是win系统和linux系统性能差别,我想也不可能啊,不能差这么多。这事就一直放在心上,有天突然想起,原来linux下是因为web和数据库放在同一台服务器上,web和数据库是通过本地进程通讯,没涉及到tcp协议。而后来win系统是分开两台,两台低层是通过TCP交流数据。由于win系统的一些默认设置,导致数据库连接池用完后没有及时释放TCP的空闲数据库连接。TCP连接就一直持续增加,慢慢超过了限制。配置了TcpTimedWaitDelay 后,TCP连接在空闲60秒后会自动释放。因此,一般情况下就保持着50个左右的稳定连接。

我想应该是如此,有时候看着数据库池好用,但其实还是对低层做了一个包装。低层的设置还是要配置一下。

-----------------------------------------华丽的分割线,测试一天后补充--------------------------------------------------------------------

第二天,故障依旧,看来不是改改注册表的事情。而且,之后查资料得知主动关闭连接的一方才会进入TIME_WAIT的状态。而数据库一般不会主动关闭连接,只有客户端主动执行了conn.close(),才会关闭数据库连接。那会是什么问题呢,我陷入了深深的思索,无果,继续谷歌百度,看了一些资料。登陆数据库服务器,执行了一下

select count(*) from v$process

查到当前连接数有147

然后执行

show parameter processes

数据库的最大连接数才150

问题在此了,那就好解释,由于后来请求数超过了oracle的最大连接数,所以对于超过数量的连接,oracle就自动断开了,才会有那么多的TIME_WAIT状态。

改大连接

alter system set processes =400 scope = spfile;

session不用改,processes 改了后session自动会根据一个比例增加,改完后我的是624

然后把数据库连接池最大值改成150

测试了一天,再没出现故障,通过netstat -ano| findstr "1521" 查询到的端口状态基本上都是established(已建立连接)和少量的LISTENING