1. 网络相关的配置(都处于/proc/sys/net包下)
1.1 复用处于TIME_WAIT的socket为新的连接所用
- 需要设置两个参数
- net.ipv4.tcp_timestamps=1(默认即为1)
- net.ipv4.tcp_tw_reuse=1
- 注意tcp_tw_reuse功能只能用于客户端(连接发起方),因为开启了该功能,在调用connect()函数时,内核会随机找一个time_wait状态超过1秒的连接给新的连接复用
- tcp_timestamps表示开启对TCP时间戳的支持,这个时间戳字段时在TCP头部的选项字段例。用于记录TCP发送方的当前时间戳和从对端接收到的最新时间戳。
- 由于引入了时间戳,2MSL存在的问题就不复存在了,因为重复的数据包会因为时间戳过期而被自然丢弃
1.2 TCP连接的保活设置
# 保活时间为2小时
net.ipv4.tcp_keepalive_time=7200
# 保活时间后每次检测间隔75秒
net.ipv4.tcp_keepalive_intvl=75
# 9次检测无响应则中断连接
net.ipv4.tcp_keepalive_probes=9
1.3 tcp重传机制如何打开SACK功能和D-SACK功能
# 开启选择性确认功能
net.ipv4.tcp_sack=1
# 开启选择性重复确认功能
net.ipv4.tcp_dsack=1
1.4 查看系统TCP第二次握手的重试次数
# 默认为5
cat /proc/sys/net/ipv4/tcp_synack_retries
1.5 查看系统设置的TCP第一次握手的重试次数
# 默认为5
cat /proc/sys/net/ipv4/tcp_syn_retries
1.6 查看系统设置的TCP连接建立后数据包传输的最大超时重试次数
# 默认是15
cat /proc/sys/net/ipv4/tcp_retries2
1.7 开启TCP Fast Open功能快速建立连接
- 如上图,开启Fast Open功能后,在第二次建立tcp连接过程中不需要再次经过三次握手。
- 第一次连接的时候,服务端会在第二次握手时产生一个Cookie并通过SYN+ACK报一起发送给客户端,于是客户端就会缓存这个Cookie。
- 客户端在第二次请求的时候,在SYN包上带上这个Cookie发送给服务端,就可以提前跳过三次握手的过程。因为Cookie中维护了一些信息,服务端可以从Cookie中获取TCP相关的信息。并进行验证
- 如果cookie有效,服务器将在syn+ack报文对syn和数据进行确认。并且服务器服务器也可以附加自己要发送的数据。
- 如果cookie无效,服务器则会在syn+ack报文中只对syn对应的序列号进行确认。不会对syn报文中包含的数据进行确认。然后等待客户端发来第三次握手ack。
- 客户端在请求并存储了 Fast Open Cookie 之后,可以不断重复使用这个cookie 直⾄服务器认为 Cookie ⽆效(过期)
- 通过设置net.ipv4.tcp_fastopen来打开Fast Open功能
- 0:关闭
- 1:作为客户端使用Fast Open功能
- 2:作为服务端使用Fast Open功能
- 3:无论作为客户端还是服务端,都可以使用Fast Open功能
1.8 如何配置某个端口tcp全连接队列的最大值
TCP全连接队列的最大值=min(somaxconn,backlog)
- somaxconn是内核参数。默认值128。 可以通过/proc/sys/net/core/somaxconn来设置
- backlog是listen(int sockfd,int backlog) 函数中的backlog大小。Nginx中默认值是511。
1.9 /proc/sys/net/ipv4/tcp_abort_on_overflow参数的用处
- 如图所示,全连接队列满了,无法再放入了。
- 处在半连接的连接收到了第三次握手ack。那么本来应该是进入ESTABLISHED状态放入全连接队列,等待被应用程序accept。但是现在因为全连接队列满了。没办法放进去了。
- 那么现在应该怎么做:
- 当tcp_abort_on_overflow=0。表示服务端会丢弃客户端发来的第三次握手ack,但是不会把连接从半连接队列中移除。服务端过一段时间后超时重发第二次握手syn+ack。会重新获取第三次握手ack。这时候全连接队列就可能不是满队列了,则就可以放入全连接队列中去。
- 当tcp_abort_on_overflow=1。表示服务端收到客户端发来的第三次ack后,会返回给客户端一个RST包。表示废掉这个握手过程和这个连接。同时将半连接队列中这个连接移除丢弃。
- 通常把tcp_abort_on_overflow=0,这样有利于应对突发流量
- 因为网络导致全连接队列满。当全连接队列有空位时。客户端发送数据时也会含有ack(相当于第三次握手)。则就会触发服务器端成功建立连接。
1.10 查看一个进程可以打开的socket描述符上限
cat /proc/sys/fs/file-max
- 如有需要,可以通过修改linux配置文件的方式修改该上限值
sudo vi /etc/security/limits.conf
# 在配置文件尾部写入以下配置,soft软限制,hard硬限制,
* soft nofile 65535
* hard nofile 100000