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.aygfsteel.com/zhyiwww   
          |----------------------------------------------------------------------------------------|
          posted on 2010-04-14 11:46 zhyiwww 閱讀(3167) 評論(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的。
            回復  更多評論
            
          主站蜘蛛池模板: 连江县| 青铜峡市| 平安县| 江津市| 芒康县| 嫩江县| 沾益县| 河津市| 云梦县| 丹江口市| 万盛区| 名山县| 扶沟县| 桐乡市| 清河县| 西安市| 桃江县| 陈巴尔虎旗| 剑阁县| 宜昌市| 平遥县| 株洲市| 大同县| 新兴县| 介休市| 安乡县| 裕民县| 方山县| 尉氏县| 山阳县| 吉林市| 汝南县| 老河口市| 洛川县| 巩留县| 榆林市| 仲巴县| 昌宁县| 衡东县| 罗源县| 达拉特旗|