Java.net.BindException: Address already in use: connect
問題原因:
操作系統會為TCP/IP服務預留臨時端口,Jmeter在跑並發測試的時候每開啟一個線程(new socket操作)就會占用一個臨時端口,若TCP/IP端口被占完了,而且沒有及時釋放(socket.close()操作不能立即釋放綁定的端口,而是把端口設置為TIME_WAIT狀態,過段時間才會真正釋放,默認是240s),就會出現Java.net.BindException: Address already in use: connect這種情況。
解決方案:
從問題的原因分析,有兩種解決方案,一是增加預留給TCP/IP服務的臨時端口的數量,二是加快被占用端口的釋放速度。
1.增加預留給TCP/IP服務的端口數量。
1.1 如果Jmeter的運行平台在Windows端。
在 Microsoft Windows XP 或 Windows Server 2003 中,由 Windows 套接字分配給應用程序的臨時 TCP 或 UDP 端口號的最大值是由注冊表設置 MaxUserPort 控制的,該參數的默認值為 5000。臨時端口從端口號 1025 開始編號。因此,默認情況下,Windows XP 或 Windows Server 2003 會為執行通配綁定的應用程序分配一個范圍從 1025 到 5000 的號碼。
要在運行 Windows XP 或 Windows Server 2003 的計算機上更改臨時端口的最大值,請執行以下操作:
1. |
單擊開始,再單擊運行,鍵入 regedit.exe,然后單擊確定。 |
2. |
找到而后單擊以下注冊表子項: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters |
3. |
在編輯菜單上,指向新建,然后單擊雙字節值。 |
4. |
鍵入 MaxUserPort,然后按 ENTER。 |
5. |
雙擊 MaxUserPort 值,然后以十進制或十六進制鍵入最大值。 鍵入的數值必須在 5000¨C65534(十進制)之間。如果此參數設置的值超出有效范圍,則使用最接近的有效值(5000 或 65534)。 |
6. |
單擊確定。 |
7. |
退出注冊表編輯器。 |
警告 如果錯誤使用注冊表編輯器,可能會導致嚴重問題以至於需要您重新安裝操作系統。Microsoft 無法保證您能夠解決由於錯誤使用注冊表編輯器而引起的問題。您必須自行承擔使用注冊表編輯器所帶來的風險。 |
必須重新啟動計算機,方可使 MaxUserPort 注冊表設置更改生效。
如果應用程序使用通配綁定同時打開大量連接,可能只需更改這個值,而且需確保應用程序不會用盡可用的臨時端口。例如,一個使用文件傳輸協議 (FTP) 傳輸大量小文件的數據備份應用程序就可能用盡臨時端口。
(具體操作見博客:https://www.cnblogs.com/zhengah/p/5102403.html)
1.2 調高你的web服務器的最大連接線程數,調到1024或者2048,以resin為例,修改resin.conf中的thread-pool.thread_max,如果你采用apache連resin的架構,別忘了再調整apache;
2. 加快被占用端口的釋放速度
在red hat上,查看有關的選項,
[xxx@xxx~]$ /sbin/sysctl -a|grep net.ipv4.tcp_tw
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_tw_recycle = 0
[xxx@xxx~]$vi /etc/sysctl,修改
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
[xxx@xxx~]$sysctl -p,使內核參數生效
3.補充(測試幾天以后)
我使用Windows平台的Jmeter,通過修改注冊表的方式開放了更多的Tcp/ip臨時端口(見1.1),剛開始效果很明顯,但是過了兩三天,又變成原樣了。這是實際測試結果,原因未知。
然后我把Jmeter部署到了Centos7操作系統上,修改配置文件sysctl(見2),就很少出現這個問題了。
(轉載請標明出處)