前言:我们在做网络优化的时候,比如客户端大量TIME_WAIT,会影响整体的并发连接数,因为客户端和服务端通讯需要建立管道通讯,标识位就是IP:PORT,按照UNIT的哲学,一个连接就是一个文件,这个文件数目是有上限的。这里说的是客户端,服务端的多路复用可以解决这个问题。
Linux系统参数学习
Some other values that server admins may need to change in /etc/sysctl.conf include
- fs.file-max – (int) max open files
- net.ipv4.ip_local_port_range – (int int) range of usable ports; state start and end (1024 65535)
- net.ipv4.tcp_tw_recycle – (bool) fast recycling of TIME_WAIT sockets
- net.ipv4.tcp_tw_reuse – (bool)
reuse of sockets in TIME_WAIT state
- net.ipv4.tcp_syncookies – (bool) use syncookies
- kernel.sched_migration_cost_ns – (int) migrate processes after X nanoseconds; useful on forking servers like Apache and PostgreSQL
- net.core.rmem_max – (int) receiving socket buffer size in bytes
NOTE: In /etc/sysctl.conf, boolean values are represented as “1” for true and “0” for false.
我们看到net.ipv4.tcp_tw_reuse
这个参数是重用TIME_WAIT的链接,这样就避免了创建大量连接,65535不够用的情况。
TTL和MSL的差异
MSL 的单位是时间,而 TTL 是经过路由跳数。所以 MSL 应该要大于等于 TTL 消耗为 0 的时间,以确保报文已被自然消亡。
- 默认MSL为2min
- 默认TTL为64
如何发现TIME_WAIT连接
这里网上找到两个命令,可以查找是哪些pid和ip:port有time_wait的情况。
查看各状态数量
netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
查看time_wait
的进程
netstat -ant| grep -i time_wait
如何合理设置net.ipv4.tcp_tw_reuse
对于客户端
- 作为客户端因为有端口65535问题,TIME_OUT过多直接影响处理能力,打开tw_reuse 即可解决
- tw_reuse 帮助客户端1s完成连接回收,基本可实现单机6w/s短连接请求,需要再高就增加IP数量;
- 业务上也可以设计由服务端主动关闭连接。
对于服务端
- 打开tw_reuse无效
- 服务器TIME_WAIT 高怎么办? 通过tcp_max_tw_buckets = 262144 配置最大上限,现代机器一般也不缺这点内存。
四次挥手
close_wait的危害在于,在一个进程上打开的文件描述符超过一定数量,(在linux上默认是1024,可修改),新来的socket连接就无法建立了,因为每个socket连接也算是一个文件描述符。
所以解决的方法有:
- 修改keepalive_time,比如设置成300s
/proc/sys/net/ipv4/tcp_keepalive_time
- 添加文件句柄数,比如设置成65534
/proc/sys/fs/file-max 是整个系统可以打开的文件数的限制,由/etc/sysctl.conf
控制;
ulimit修改的是当前shell和它的子进程可以打开的文件数的限制,由/etc/security/limits.conf
控制;
根本原因,一般就是服务端超时了一直在处理,客户端主动关闭了造成的,或者是客户端不正常的关闭,比如数据库操作异常了,也没rollback等,最终服务端发送FIN信息,客户端还会有给服务端一个RST。
声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/206849.html