Linux 文件打开最大数
1 | vi /etc/security/limits.conf |
参考:Linux最大文件打开数
内核优化
方法一:修改 /proc
下内核参数文件内容,不能使用编辑器来修改内核参数文件,理由是由于内核随时可能更改这些文件中的任意一个,另外,这些内核参数文件都是虚拟文件,实际中不存在,因此不能使用编辑器进行编辑,而是使用echo命令,然后从命令行将输出重定向至 /proc
下所选定的文件中。如:将 timeout_timewait
参数设置为30秒:
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
参数修改后立即生效,但是重启系统后,该参数又恢复成默认值。因此,想永久更改内核参数,需要修改/etc/sysctl.conf文件
方法二.修改 /etc/sysctl.conf
文件
优化适合apache
,nginx
,squid
多种等web应用。
文件:/etc/sysctl.conf
1 | # 表示套接字由本端要求关闭,这个参数决定了它保持在FIN-wAIT-2状态的时间,默认值是60秒 |
reuse/recycle注解:
因为TCP连接是双向的,所以在关闭连接的时候,两个方向各自都需要关闭。先发 FIN
包的一方执行的是 主动关闭
;后发 FIN
包的一方执行的是 被动关闭
。主动关闭的一方会进入TIME_WAIT
状态,并且在此状态停留两倍的 MSL
maximum segment lifetime(最大分节生命期
或最大报文存活时间
,这是一个IP数据包能在互联网上生存的最长时间,超过这个时间IP数据包将在网络中消失 。MSL在RFC 1122上建议是2分钟,而源自berkeley的TCP实现传统上使用30秒。一般Linux内核设置30秒 )时长。TIME_WAIT
状态维持时间是两个MSL时间长度,也就是在1-4分钟。Windows操作系统就是4分钟。
等待 2MSL
原因:
TCP目的是可靠传输,主动关闭的一方发出 FIN
,被动方回复ACK
,接着被动方发送 FIN
,主动方收到被动关闭的一方发出的 FIN
包后,回应 ACK
包,同时进入 TIME_WAIT
状态。但是因为网络原因,主动关闭的一方发送的这个 ACK
包很可能延迟,从而触发被动连接一方重传 FIN
包。极端情况下,这一去( ACK
去被动方)一回(重传 FIN
回来),就是两倍的 MSL
时长。
如果主动关闭的一方跳过 TIME_WAIT
直接进入 CLOSED
,或者在 TIME_WAIT
停留的时长不足两倍的 MSL
,那么当被动关闭的一方早先发出的 FIN
延迟包到达或者重传 FIN
包到达后,就可能出现类似下面的问题:
- 主动方旧的TCP连接已经不存在了,主动方只能返回RST包
- 主动方新的TCP连接被建立起来了,延迟包可能干扰新的连接
减少TIME_WAIT
TIME_WAIT
期间,资源不会释放,现在都追求高性能高并发,快速释放资源是躲不掉的.对于客户端因为有端口 65535
问题,TIME_WAIT
过多直接影响处理能力. 对于服务器,无端口数量限制的问题,Linux优化也很给力,每个处于 TIME_WAIT
状态下连接内存消耗很少, 而且也能通过 tcp_max_tw_buckets = ${你要的阈值}
配置最大上限,但是对于短连接为主的web服务器,几十万的连接,基数很大,耗得内存也不小,快速释放总是好的。
tcp_tw_recycle:回收TIME_WAIT连接
对客户端和服务器同时起作用,开启后在 3.5*RTO 内回收,RTO 200ms~ 120s 具体时间视网络状况。RTO(Retransmission TimeOut)重传超时时间。内网状况比 tcp_tw_reuse
稍快,公网尤其移动网络大多要比 tcp_tw_reuse
慢,优点就是能够回收服务端的 TIME_WAIT
数量。
但是,需要注意的是:当多个客户端通过NAT方式联网并与服务端交互时,服务端看到的是同一个IP,也就是说对服务端而言这些客户端实际上等同于一个,可惜由于这些客户端的时间戳可能存在差异,于是乎从服务端的视角看,便可能出现时间戳错乱的现象,进而直接导致时间戳小的数据包被丢弃。客户端处于NAT很常见,基本公司家庭网络都走NAT。
tcp_tw_reuse
:复用 TIME_WAIT
连接 只对客户端起作用,1秒后才能复用,当创建新连接的时候,如果可能的话会考虑复用相应的 TIME_WAIT
连接。通常认为 tcp_tw_reuse
比tcp_tw_recycle
安全一些,这是因为一来 TIME_WAIT
创建时间必须超过一秒才可能会被复用;二来只有连接的时间戳是递增的时候才会被复用。
客户端请求服务器,服务器响应后主动关闭连接,TIME_WAIT
存在于服务器,服务器是被连接者,没有复用一说,所以只对客户端起作用.如果是客户端主动关闭, TIME_WAIT
存在于客户端,这个时候再次连接服务器,可以复用之前 TIME_WAIT
留下的半废品。
tcp_timestamps
:以上两点,必须在客户端和服务端 timestamps
开启时才管用(默认开启) 需要根据 timestamp
的递增性来区分是否新连接
总结
客户端 tcp_tw_reuse
复用连接管用, tcp_tw_recycle
有用,但是客户端主要不是接受连接,用处不大
服务器 tcp_tw_recycle
回收连接管用,tcp_tw_reuse
复用无效.为了减少 TIME_WAIT
留在服务器,可以在服务器开启 KeepAlive
,尽量不让服务器主动关闭,而是客户端主动关闭,减少TIME_WAIT
产生。
1 | # 表示开启SYN Cookies功能,当出现SYN等待队列溢出时,启用Cookies来处理,可防范少量SYN攻击, |
listen方法指定的backlog是在用户态指定的,内核态的参数优先级高于用户态的参数,所以即使在listen方法里面指定backlog是一个大于somaxconn的值,socket在内核态运行时还会检查一次somaxconn,如果连接数超过somaxconn就会等待。
在没有调优的centOS7.4版本的服务器上,由于受到系统级别的限制,在该服务器上运行的服务端程序,在同一时间,最大只能接受128个客户端发起持久连接,并且只能处理128个客户端的数据通信。
1 | # 表示系统同时保持 TIME_WAIT 套接字的最大数量,如果超过这个数值,TIME_WAIT 套接字将立刻被清除并打印警告信息, |
/etc/sysctl.conf
1 | net.ipv4.tcp_fin_timeout = 30 |
查看系统级文件句柄修改,是否生效
1 | sysctl -p |
备忘录:
1 | # 获取操作系统参数的类型 |
参考: