为什么会产生这么多 time-wait?谁主动关闭谁就有 time-wait
客户端有很多time wait,redis报:Cannot assign request
说明是大量短链接客户端端口号不够了
linux TIME_WAIT 相关参数:
net.ipv4.tcp_tw_reuse = 0 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭
net.ipv4.tcp_tw_recycle = 0 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭
net.ipv4.tcp_fin_timeout = 60 表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间(可改为30,一般来说FIN-WAIT-2的连接也极少)
注意:
- 不像Windows 可以修改注册表修改2MSL 的值,linux 是没有办法修改MSL的,tcp_fin_timeout不是2MSL 而是Fin-WAIT-2状态.
- tcp_tw_reuse 和SO_REUSEADDR 是两个完全不同的东西
SO_REUSEADDR 选项用于通知内核:
如果端口忙,并且端口对应的TCP连接状态为TIME_WAIT,则可以重用端口;
如果端口忙,并且端口对应的TCP连接处于其他状态(非TIME_WAIT),则返回 “Address already in use” 的错误信息。
设置SO_REUSEADDR的风险是可能会导致新连接上收到旧连接的数据(复用了旧连接的端口,导致新旧连接的四元组完全一致,内核协议栈无法区分这两个连接)。
SO_REUSEADDR 选项并没像 tcp_tw_reuse 那样同时提供一个 tcp_timestamp 参数可以设置 TIME_WAIT的等待时长。
可以通过sysctl查看
sysctl -a|egrep "tw_reuse|timestamp|local_port"
通过sysctl设置
sysctl -w sysctl -w net.ipv4.tcp_timestamps=1
sysctl -w net.ipv4.tcp_tw_reuse=1
对于客户端
1.作为客户端因为有端口65535问题,TIME_OUT过多直接影响处理能力,打开tw_reuse 即可解决,不建议同时打开tw_recycle,帮助不大。
2.tcp_tw_reuse帮助客户端1s完成连接回收,基本可实现单机6w/s请求,需要再高就增加IP数量吧。
3.如果内网压测场景,且客户端不需要接收连接,同时tw_recycle 会有一点点好处。
4.业务上也可以设计由服务端主动关闭连接
或
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
echo 1 > /proc/sys/net/ipv4/tcp_timestamp
或
vi /etc/sysctl.conf 编辑文件,加入以下内容:
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_timestamp = 1
sysctl -p让参数生效。
1. tw_reuse,tw_recycle 必须在客户端和服务端tcp_timestamps 开启时才管用(默认打开)
2. tw_reuse 只对客户端起作用,开启后客户端在1s内回收
3. tw_recycle 对客户端和服务器同时起作用,开启后在 3.5*RTO 内回收,RTO 200ms~ 120s 具体时间视网络状况。
内网状况比tw_reuse稍快,公网尤其移动网络大多要比tw_reuse 慢,优点就是能够回收服务端的TIME_WAIT数量
网络优化之net.ipv4.tcp_tw_recycle和tcp_tw_reuse参数
Redis:Cannot assign requested address的解决办法
一系列写入文本命令的处理:
 Redis 命令行redis-cli使用$ cat /tmp/commands.txt
SET arg_example "This is a single argument"
STRLEN arg_example
$ cat /tmp/commands.txt | redis-cli
OK
(integer) 25
redis-cli 批量删除太多wait time解决:等您坐沙发呢!