• TCP的优化


    TCP的优化?

    TCP三次握手的性能提升

    客户端优化

    当客户端发送SYN报文后会进入SYN_SENT状态,正常情况下服务器会在毫秒内返回ACK+SYN,但当发生丢包触发客户端的重传机制时,客户端需要等待1…3…7…15…31…63s,也就是需要在重传5次之后才会断开连接(重传最大次数有tcp_syn_retries参数决定),因此可以根据网络的稳定性和服务器的繁忙程度修改SYN重传次数

    服务端优化

    1. 半连接队列满

      增大半连接队列大小:增大tcp_max_syn_backlog和somaxconn以及backlog参数的大小,后两者的最小值是全连接队列的大小

      开启tcp_syncookies机制.

      减少ACK+SYN报文重传次数:修改tcp_synack_retries

    2. 全连接队列满

      丢弃/回复RST报文(设置tcp_abort_on_overflow:0/1)

      增大全连接队列长度:增大somaxconn和backlog参数的大小.

    如何绕过三次握手

    引入快速连接(TCP fast open)机制.

    传统的TCP连接需要消耗最少一个RTT后才能开始发送HTTP请求.但快速连接可以在建立一次连接之后,之后每次建立连接耗费的时间都是0RTT.

    TFO过程:

    第一次建立连接时:客户端发送SYN报文并在SYN报文中添加空的Cookie选项;服务器接收到SYN报文后会生成Cookie然后保存在SYN+ACK报文发送给客户端,客户端将Cookie缓存到本地;之后就客户端就可以发送数据了.

    第二次建立连接时:客户端发送的SYN中包含数据和Cookie,服务器接收后验证Cookie的有效性,如果有效就返回响应和ACK报文.至此可以节省一个RTT.如果Cookie失效则会只发送ACK报文.

    Cookie的值是保存在option选项中的.在Linux中,可以通过调整tcp_fastopn参数开始快速连接机制(1:客户端开启TFO,2:服务器开启TFO,3:任意一方开启TFO)

    TCP四次挥手的性能提升

    发送方优化

    关闭连接的方式分为两种:分别是RST报文关闭和FIN报文关闭.其中前者属于暴力关闭,不经历四次握手的过程,安全的连接方式需要通过四次握手,由进程调用close函数或shutdown函数发起FIN报文.

    close函数意味着完全关闭连接,即调用close函数的一方之后既不能发送数据,也不能接收数据.

    shutdown函数可以通过参数来控制关闭的程度

    RD:关闭连接的读.即不能再接收数据.会将接收缓冲区中的数据丢弃,即使对端发送了数据报文也会在回复ACK后将报文丢弃.

    WR:关闭连接的写.即不能再发送数据.如果发送缓冲区中有数据会立即发送,并发送一个FIN报文.

    RDWR:关闭连接的读和写,即不能接收数据和发送数据.

    FIN_WAIT1的优化

    发送方发送了FIN报文后会进入FIN_WAIT1状态,在接收到接收方的ACK报文后会迅速进入到FIN_WAIT2状态.但当发生丢包时会触发发送方重传FIN报文,因此可以通过减少重传次数来加速发送方断开连接,即减少tcp_orphan_retries参数的值(默认是8).

    但有时候当遇到恶意攻击时会导致连重发的FIN报文也无法发送(恶意攻击导致接收方窗口大小为0致使发送方无法发送数据,而发送方的发送缓冲区中的数据没有发送完,FIN报文需要在数据发送完后再发送).这时候需要调整tcp_max_orphans参数来降低最大的孤儿连接数量.当孤儿连接数量大于tcp_max_orphans的值时,新的孤儿连接会直接回复RST报文.

    FIN_WAIT2的优化

    当发送方接收到接收方的ACK报文后会进入FIN_WAIT2状态.如果调用的是shutdown函数,因为可能还可以继续发送或接收数据,所以发送方可以一直处于FIN_WAIT2状态.但如果调用的是close函数,那么则会处于孤儿连接,因此在FIN_WAIT2状态不能持续太长时间,这个时间有tcp_fin_timeout参数决定,通常是60s(超过60s会直接关闭连接.),和TIME_WAIT一致.

    TIME_WAIT状态的优化

    1. 通过tcp_max_tw_buckets参数来控制TIME_WAIT的最大连接,当超过这个值,新关闭的连接将不经过TIME_WAIT状态而直接关闭.
    2. 在建立连接时,复用在TIME_WAIT状态的连接超过1s的连接.通过打开tcp_tw_reuse参数(注意:该参数只能由客户端发起,因为是在调用connect方法时发挥作用的.),同时也要将时间戳打开(通信双方都需要打开)
    3. 通过tcp_tw_recycle参数回收TIME_WAIT状态的连接(不推荐).当开启recycle和timestamp时,就会开启per-host的PAWS(判断TCP报文中的时间戳是否失效).per-host是对对端IP做PAWS检查,这就面临一个问题:当对端是通过NAT网关后进行通信,不同的客户端经过相同的NAT网关后的IP地址是相同,per-host无法判断对方的时间戳是哪一个客户端的,容易发生误判.优化方式就是对四元组做PAWS检查.
    4. 通过设置socket参数来跳过TIME_WAIT状态:将l_onoff设置为非0,l_linger设置为0,在调用close函数会直接回复RST报文来中断连接.

    接收方优化

    接收方在发送了FIN报文后会进入LAST_ACK状态,如果收不到ACK会触发重传,与发送方一样,可以通过设置tcp_orphan_retries来加速连接的断开.

    注意:接收方发送ACK报文和FIN报文之间如果没有数据发送,则ACK报文和FIN报文可能会同时发送.

    当通信双方同时关闭连接时,即同时给对方发送FIN报文后,会同时进入FIN_WAIT1状态,所以上述的优化策略仍然成立.之后会给对方传输ACK报文,传输后会进入新的状态CLOSEING,在对方接收到ACK后会进入TIME_WAIT状态,等待2MSL时间后关闭连接.在这里插入图片描述

    TCP数据传输的性能提升

    1. 扩大滑动窗口大小:tcp_window_scaling.可以让滑动窗口从默认的最大值64KB调整为1GB
    2. 内核缓冲区决定了滑动窗口的大小,将内核缓冲区的上限设置为带宽时延积,带宽时延积是网络中能够承载的数据的最大数量,通过带宽与RTT相乘得到.tcp_wmem是调整发送缓冲区的大小,tcp_rmem是调整接收缓冲区的大小.
    3. 发送缓冲区的大小是自动动态调节的,而接收缓冲区的动态调节功能可以通过tcp_moderate_rcvbuf打开.
  • 相关阅读:
    RestTemplat
    【linux】stat文件属性中三个时间的区别(Access time,Modify time,Change time)
    【小尘送书-第五期】《巧用ChatGPT快速提高职场晋升力》用ChatGPT快速提升职场能力,全面促进自身职业发展
    I.MX6ULL ARM驱动开发---块设备驱动
    Java中的代码优雅重构实战
    说一说:ThreadLocal 、CallContext 、AsyncLocal
    【无标题】
    教育src漏洞挖掘-2022-白帽必挖出教程
    新药发明专利的专利权期限。
    物联网网关:连接设备与云端的桥梁
  • 原文地址:https://blog.csdn.net/weixin_52477733/article/details/126652583