天天看點

Linux Cannot assign requested address

ConnectException: Cannot assign requested address (connect failed)

原因

在存在大量短連接配接的情況下,雖然 socket 正常關閉,但預設60s後釋放,而不是立即釋放,是以處于TIME_WAIT狀态。Linux 連接配接端口(65535)用盡,就會造成這個異常。

檢視

檢視程序,有很多 TIME_WAIT 狀态的。

netstat -a | grep -i time_wait           
Linux Cannot assign requested address

 總數

netstat -ant | grep -i time_wait | wc -l           
Linux Cannot assign requested address

解決

注意:需root權限

1. 臨時修改 sysctl

sysctl -w     # 臨時修改指定系統參數的值
       -p     # 從指定的檔案加載系統參數,如不指定則加載/etc/sysctl.conf
       -a     # 顯示所有系統參數           
# 端口釋放後的等待時間,預設為60s
sysctl -w net.ipv4.tcp_fin_timeout=30

# 或者更快回收設定
# 開啟對于TCP時間戳的支援,0關閉,則下面兩項設定不起作用
sysctl -w net.ipv4.tcp_timestamps=1

# 用戶端設定
# 允許端口重用,隻對用戶端起作用,開啟後用戶端在1s内回收time-wait socket
sysctl -w net.ipv4.tcp_tw_reuse=1

# 開啟TCP連接配接快速回收time-wait socket資源,預設為0關閉
# 用戶端不需要開啟
# 非高并發伺服器不建議開啟,開啟後在 3.5*RTO 内回收,RTO 200ms~ 120s,具體時間視網絡狀況
sysctl -w net.ipv4.tcp_tw_recycle=1

# 另外
# 檢視可用端口範圍,預設 32768~60999,不到3w
sysctl -a | grep port_range

# 可設定tcp_max_tw_buckets
# 當 time_wait 數量等于 tcp_max_tw_buckets,不産生新的 time_wait
sysctl -w net.ipv4.tcp_max_tw_buckets=5000

           

或者

echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
echo 1 > /proc/sys/net/ipv4/tcp_timestamps
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle

sysctl -p             

2. 永久修改

将配置寫入 /etc/sysctl.conf。

vim /etc/sysctl.conf

# 添加
net.ipv4.tcp_timestamps=1
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1

sysctl -p           

繼續閱讀