Cannot assign requested address以及大量的TIME_WAIT解决办法

来源:互联网 发布:淘宝嘉年华什么时候 编辑:程序博客网 时间:2024/05/18 20:11
curl在服务器上提示“Cannot assign requested address”错误,这是由于curl客户端频繁的连服务器,由于每次连接都在很短的时间内结束,导致很多的TIME_WAIT,以至于用光了可用的端口号,所以新的连接没办法绑定端口。端口号的数量取决于一个内核参数net.ipv4.ip_local_port_range:
sysctl -a | grep portnet.ipv4.ip_local_port_range = 32768 61000
因为端口范围是一个闭区间,所以实际可用的端口数量是:echo $((61000-32768+1))为28233个

进一步,通过netstat -an,看到很多TIME_WAIT状态的连接。
netstat -nt | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'

根据TCP协议定义的3次握手断开连接规定,发起socket主动关闭的一方 socket将进入TIME_WAIT状态,TIME_WAIT状态将持续2个MSL(Max Segment Lifetime),MSL 的 RFC 1122[Braden 1989]的建议值是2分钟,不过源自Berkeley的实现传统上改用30秒这个值,在Windows下默认为4分钟,即240秒,这意味着TIME_WAIT状态的持续时间在1分钟到4分钟之间。而TIME_WAIT状态下的socket不能被回收使用。 具体现象是对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT状态的socket, 甚至比处于Established状态下的socket多的多,严重影响服务器的处理能力,甚至耗尽可用的socket,停止服务. TIME_WAIT是TCP协议用以保证被重新分配的socket不会受到之前残留的延迟重发报文影响的机制,是必要的逻辑保证.

修改方法:
1、增加端口号数量
2、减少TIME_WAIT连接状态

windows下:
     在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters,添加名为TcpTimedWaitDelay的DWORD键,设置为60,以缩短TIME_WAIT的等待时间

linux下:
通过调整内核参数解决,vim /etc/sysctl.conf,加入
net.ipv4.tcp_syncookies = 1 #表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1 #表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 #表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout = 3 #修改系統默认的 TIMEOUT 时间
net.ipv4.tcp_max_tw_buckets = 10000#通过设置它,系统会将多余的TIME_WAIT删除掉,此时系统日志里可能会显示:『TCP: time wait bucket table overflow』,多数情况下不用在意这些信息。

然后执行 /sbin/sysctl -p 让参数生效。