現象:
[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.tkk7.com/zhyiwww
|----------------------------------------------------------------------------------------|
posted on 2010-04-14 11:46
zhyiwww 閱讀(3164)
評論(6) 編輯 收藏 所屬分類:
j2ee