现象:
[1]多线程启动频繁操作MSSQL,抛出
到主机 的 TCP/IP 连接失败。 java.net.BindException: Address already in use: connect
[2]在服务器上,执行netstat -a,可以看到很多TCP TIME_WAIT
很多端口被占用
类似下面的:
TCP 127.0.0.1:1025 127.0.0.1:1433 TIME_WAIT
TCP 127.0.0.1:1026 127.0.0.1:1433 TIME_WAIT
TCP 127.0.0.1:1027 127.0.0.1:1433 TIME_WAIT
TCP 127.0.0.1:1028 127.0.0.1:1433 TIME_WAIT
......
TCP 127.0.0.1:4998 127.0.0.1:1433 TIME_WAIT
TCP 127.0.0.1:4999 127.0.0.1:1433 TIME_WAIT
TCP 127.0.0.1:5000 127.0.0.1:1433 TIME_WAIT
开始,我跑2个线程都有问题,过一会程序就抛上面的异常。
我现在用了一个可行的方案,不是最好的方案。
两步操作:
[1]通过修改注册表
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters:
添加或者修改下面两项
MaxUserPort = dword:00004e20 (20,000 decimal)
TcpTimedWaitDelay = dword:0000001e (30 decimal)
我的值设置
MaxUserPort值修改为十进制60000
TcpTimedWaitDelay值修改为十进制10
MaxUserPort是最大的可用端口,最大值也就是65535了
TcpTimedWaitDelay就是默认的TimeWait时间,默认是30,改小了,可以提高响应速度。
经过实践,修改此两项参数是很有效的方法。
[2]修改程序
在对线程控制上,需要频繁对数据库操作的地方,实现让线程休眠一段时间
for(int i = 0;i<100000;i++){
TestThread t = new TestTread();//频繁对数据库操作
t.start();
try {
this.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
原因分析:
JDBC Connection 关闭后,释放了对数据库连接的资源,但是对与服务器的Socket连接并没有完全释放。TCP在处理一个新的请求的时候,会创建新的连接,TIME_WAIT状态的连接在4分钟后释放。所以,如果在4分钟内就把连接端口资源用完的话,就会出现上面的异常。如果4分钟后,前面用去的端口得到释放,取得和释放达到一个平衡,就不会再出现此异常了。
默认的MaxUserPort是5000,这个值对于多线程来说,很容易就达到了。所以,如果线程跑的多,很容易就跑死了。
根本解决:
还是要从程序上下功夫。
[1]避免频繁操作问题
如果是检索,不要一个一个检索,一次检索到列表里面再进行处理。
如果数据量很大,那就用分页操作进行处理。
如果是其他的操作,添加,删除,修改的话,就可以使用批量操作来进行。这样,可以少去频繁取连接。就可以避免上面的问题。
[2]资源释放要快
数据库资源要及时释放。
包括Resulset,Statement,Connection
要及时关闭
如果数据库操作特别频繁,可以考虑使用连接共用。
这样,虽然连接占用的时间长点,但是,不会出现上面的问题。
在数据导入的程序里面还是很有用的。
[3]可以考虑使用连接池来提升系统共享上的性能。
|----------------------------------------------------------------------------------------|
版权声明 版权所有 @zhyiwww
引用请注明来源 http://www.blogjava.net/zhyiwww
|----------------------------------------------------------------------------------------|
posted on 2010-04-14 11:46
zhyiwww 阅读(3156)
评论(6) 编辑 收藏 所属分类:
j2ee