4.10 tcp 被遗弃的参数 tcp_recycle

为什么出现这个参数

  • 在大并发的场景下 单机的tcp连接的文件描述符被耗尽了

为什么会被耗尽

  • 进程文件描述符限制
// 默认1024
ulimit -n
//  当前临时修改 /etc/security/limits.conf 
soft nofile 1000000
hard nofile 1000000
// 永久修改 /etc/rc.local
ulimit -SHn 1000000
  • 系统文件描述符限制
//查看 
cat /proc/sys/fs/file-nr

// 永久修改 /etc/sysctl.conf
fs.file-max = 1000000
net.ipv4.ip_conntrack_max = 1000000
net.ipv4.netfilter.ip_conntrack_max = 1000000

``
* 网络中端口和IP限制

// 网络唯一标识一个链接 四元组 local ip, local port,remote ip,remote port
// 不考虑地址重用(unix的SO_REUSEADDR选项)的情况下,
// 即使server端有多个ip,本地监听端口也是独占的 local ip, local port 已经确定了
// local ip, local port, 2的32次方(ip数)×2的16次方(port数)
// 操作系统上端口号1024以下是系统保留的,从1024-65535是用户使用的
// IP 私有网段、网络ID、广播ID、保留网段、本地环回127.0.0.0网段、组播224.0.0.0网段 大约36亿
// 因此理论上就是 2的48次方



#### 如何最大程度的这个这些连接 就是回收
* 在 linux 4.1  tcp_recycle 被废弃了
* 其实大部分不能回收的原因在timewait 主动断开的方的 等待2ML时间内
* 第二由于 tcp 初始化的ts 在初始化的 基本一致 导致 ts造成的新旧连接包冲突
* TIME_WAIT状态就是为了让旧连接能够完全释放 但是又是没被释放则 又被重复使用 导致链接被重置
*  对于Linux,字段为TCP_TIMEWAIT_LEN硬编码为30秒,对于windows为2分钟(可自行调整)。
*  如果客户端跳过TIME_WAIT阶段进入了CLOSED,服务端始终无法得到响应,就会处于LAST-ACK状态,此时假如客户端发起了一个新连接,则会以失败告终。

ss -tan state time-wait|wc -l
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'


### TIME_WAIT的危害
* 占用连接资源TIME_WAIT占用的1分钟时间内,相同四元组(源地址,源端口,目标地址,目标端口)的连接无法创建,
* 通常一个ip可以开启的端口为net.ipv4.ip_local_port_range指定的32768-61000,如果TIME_WAIT状态过多,会导致无法创建新连接。
* 占用内存资源 这个占用资源并不是很多,可以不用担心

### TIME_WAIT的解决
*.修改为长连接,代价较大,长连接对服务器性能有影响。
*..增加可用端口范围(修改net.ipv4.ip_local_port_range); 增加服务端口,比如采用80,81等多个端口提供服务; 增加客户端ip(适用于负载均衡,比如nginx,采用多个ip连接后端服务器); 增加服务端ip; 这些方式治标不治本,只能缓解问题。
*..将net.ipv4.tcp_max_tw_buckets设置为很小的值(默认是18000). 当TIME_WAIT连接数量达到给定的值时,所有的TIME_WAIT连接会被立刻清除,并打印警告信息。但这种粗暴的清理掉所有的连接,意味着有些连接并没有成功等待2MSL,就会造成通讯异常。
*.修改TCP_TIMEWAIT_LEN值,减少等待时间,但这个需要修改内核并重新编译。
*..打开tcp_tw_reuse和tcp_timestamps选项。

### 为什么 tcp_recycle  被遗弃
*  启用TIME_WAIT 状态的sockets的快速回收,影响所有连入和连出的连接 
*  重点: Linux会丢弃所有来自远端的timestramp时间戳小于上次记录的时间戳(由同一个远端发送的)的任何数据包。也就是说要使用该选项,则必须保证数据包的时间戳是单调递增的。
*  问题在于,此处的时间戳并不是我们通常意义上面的绝对时间,而是一个相对时间。很多情况下,我们是没法保证时间戳单调递增的,比如使用了nat,lvs等情况。
*  将net.ipv4.tcp_tw_recycle设置为1,却忽略了该选项的局限性,最终造成严重的后果(比如我们之前就遇到过部署在nat后端的业务网站有的用户访问没有问题,但有的用户就是打不开网页)。
*   tcp_tw_reuse 和 tcp_timestamps相互配合只是在客户端一侧超过1s可以被复用
*   终极大招 : 那么从4.10内核开始,官方修改了时间戳的生成机制。因为随机化的时间戳偏移量已经提供了更加有效和安全的替代方案。


### 为什么随机化偏移时间戳更安全
* 抵御重放攻击:随机化时间戳偏移量可以在一定程度上抵御时间戳重放攻击。通过引入随机性,使得攻击者难以正确预测下一个时间戳的值,从而降低了时间戳被利用进行重放攻击的可能性。
* 避免连接混乱:随机化时间戳偏移量可以减少新旧连接之间的混淆和冲突,因为每个连接的时间戳偏移量都是随机生成的,不容易与其他连接产生冲突。
*兼容性更好:tcp_tw_recycle 在某些特定的网络环境中可能会导致一些意外的连接问题,而随机化时间戳偏移量作为对时间戳问题的更普适和更有效的解决方案,具有更好的兼容性和可靠性。
posted @ 2024-03-19 15:46  vx_guanchaoguo0  阅读(28)  评论(0编辑  收藏  举报