zhyiwww
用平实的笔,记录编程路上的点点滴滴………
posts - 536,comments - 394,trackbacks - 0
现象:
[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 阅读(3148) 评论(6)  编辑  收藏 所属分类: j2ee

FeedBack:
# re: 多线程频繁操作MSSQL导致java.net.BindException异常的解决方法
2010-04-14 11:48 | fzming
听说过长连接吗  回复  更多评论
  
# re: 多线程频繁操作MSSQL导致java.net.BindException异常的解决方法[未登录]
2010-04-14 13:46 |
可能是socket没有完全关闭导致的。
建议你尝试下回收mysql的连接,不要用完就关闭,这样会比较浪费资源。而且频繁启动新连接,也不是一种很有效率的做法。  回复  更多评论
  
# re: 多线程频繁操作MSSQL导致java.net.BindException异常的解决方法
2010-04-14 16:29 | 税国政
说到关闭连接, 我以被他挂了两次了  回复  更多评论
  
# re: 多线程频繁操作MSSQL导致java.net.BindException异常的解决方法
2010-04-14 18:21 | 隔叶黄莺
第一个反应就是使用连接池  回复  更多评论
  
# re: 多线程频繁操作MSSQL导致java.net.BindException异常的解决方法
2010-04-17 11:38 | 俏物悄语
可能是socket没有完全关闭导致  回复  更多评论
  
# re: 多线程频繁操作MSSQL导致java.net.BindException异常的解决方法
2010-04-21 11:01 | zhyiwww
已经关闭了连接,也释放了所有的资源。
在JDBC中是关闭不到Socket的。
  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: