美文网首页
Linux TCP优化

Linux TCP优化

作者: BoatingTao | 来源:发表于2023-06-21 20:34 被阅读0次

    优化方面

    Listen状态下的半连接队列以及全连接队列
    TCP挥手快速回收,心跳机制调优
    异常状态下TCP处理逻辑,超时重传次数

    阐述:
    服务端收到客户端发起的SYN握手请求后,内核会把该连接存储到半连接队列,并响应客户端SYC+ACK(此时服务端状态SYN_RECV),接着客户端会返回ACK。
    服务端收到ACK后,内核会把连接从半连接队列移除,然后创建新的完全的连接,并将其添加到全连接队列,等待进程调用accept函数时把连接取出来。

    非Listen状态
    Send-Q:全连接队列,send queue中bytes数值
    Recv-Q:半连接队列,receive queue中bytes数值

    Listen状态
    Send-Q:全连接队列,min(backlog, somaxconn) somaxconn默认为128(笔者虚拟机),backlog由listen时传入
    Recv-Q:半连接队列,完成连接的数量 max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog) tcp_max_syn_backlog默认128

    • 统计分析
    统计半连接连接个数
    netstat -natp|grep -i 'syn_recv' |wc -l
    
    统计半连接队列已满造成的失败次数,这是累计值
    netstat -s |grep -i 'syns to listen'
    
    统计TCP socket连接因为全连接队列、半连接队列满了而被丢弃
    netstat -s |grep -i 'listen'
          189000 times the listen queue of a socket overflowed  代表 189000 次全连接队列溢出
           30150000 SYNs to LISTEN sockets dropped 代表 30150000 次半连接队列溢出
    
    如果这两个值一段时间内相关数值一直上升,则表明半连接队列、全连接队列有溢出情况
    
    
    ss -lnt
    ss命令可快速查看网络连接状态
    

    注意,调整参数笔者建议修改 /etc/sysctl.conf 文件

    • 全连接、半连接队列相关参数优化
    TCP 连接队列相关解释,如果半连接或者全连接队列超过长度大小限制,内核会丢弃或者返回RST报文。
    
    1.超出队列大小后内核对于握手报文的处理
    cat /proc/sys/net/ipv4/tcp_abort_on_overflow
    0(默认,建议)
    参数值为 0: 全连接队列满了,server扔掉client发送的ack
    客户端认为服务端并未收到ACK,然后重传,服务端继续扔掉ACK,然后重传SYN+ACK直到客户端加入全连接队列或者达到双方重传上限次数。
    会造成客户端 connection time out错误,errno=110
    
    参数值为 1:全连接队列满了,新的连接不能加入,server发送reset包给client
    TCP全连接队列溢出,会造成客户端connection reset by peer的错误,errno=104
    
    2. 调整全连接队列大小
    全连接队列的最大值取值 min(somaxconn, bakclog)
    cat /proc/sys/net/core/somaxconn
    128(默认)
    
    echo 1024 > cat /proc/sys/net/core/somaxconn
    backlog是listen(int sockfd, int backlog)中backlog的大小,如果是Nginx
    listen 8080 default backlog=1024 (如果已经调整了上面两个参数1024,nginx默认启动后全连接队列就是511)
    
    不同的Web服务配置不同,看看源码是什么参数
    
    将 tcp_abort_on_overflow 设置为 1 ,如果客户端收到很多 reset 报文,则全连接队列可能太小了。
    调整完全连接队列后,tcp_abort_on_overflow  还是建议为 0 ,以应对突发情况。因为不会立即返回 reset,会给客户端重试机会。
    
    3. 调整半连接队列大小
    单纯增大半连接没有用处,得全连接队列也增大。
    /proc/sys/net/ipv4/tcp_max_syn_backlog
    128(默认)
    
    
    4. 系统同时保持tw状态的连接数量
    系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数量,TIME_WAIT套接字会被立即清楚并打印警告信息
    cat /proc/sys/net/ipv4/tcp_max_tw_buckets
    16384(默认)
    
    
    5. client端syn重传次数
    cat /proc/sys/net/ipv4/tcp_syn_retries
    6(默认)
    重传的时间周期:(1s后重传->2s后重传->4s->8s->16S->32s->64s)
    建议调整
    调整为1的示例:
    echo 1 > /proc/sys/net/ipv4/tcp_syn_retries
    
    6.server端syn+ack重传次数
    cat /proc/sys/net/ipv4/tcp_synack_retries
    5(默认)
    重传的时间周期:(1s后重传->2s后重传->4s->8s->16S->32s)
    
    
    7.开启syncookies
    echo 1 > /proc/sys/net/ipv4/tcp_syncookies
    
    • 预防SYN攻击
    预防SYN攻击===> 笔者认为内网应该很少遇见
    
    1.增加半连接队列的大小
    ++ tcp_max_syn_backlog
    ++ somaxconn
    ++ backlog
    
    2.开启tcp_syncookies
    cat /proc/sys/net/ipv4/tcp_syncookies
    1
    默认是1 ,表示在syn backlog(tcp_max_syn_backlog)队列满员时会开启此功能
    
    调整为2,表视无条件开启syncookies功能
    
    3.减少SYN+ACK 重传次书
    echo 1 >  /proc/sys/net/ipv4/tcp_synack_retries
    
    • TCP挥手优化
    TCP挥手优化
    
    1.开启syncookies
    cat /proc/sys/net/ipv4/tcp_syncookies
    1
    建议调整为1
    
    2.调整TCP回收时间, 新的连接可以立即使用TIME-WAIT状态下的连接
    cat /proc/sys/net/ipv4/tcp_tw_reuse
    1
    建议调整为1
    
    3.开启TCP连接中TIME-WAIT的快速回收
    cat /proc/sys/net/ipv4/tcp_tw_recyle
    1
    建议调整为1
    
    注意:2和3建议开启2网上推荐的。笔者自测发现开启3就能快速回收TIME_WAIT。
    
    
    4.调整tcp fin wait 2状态的超时时间
    cat /proc/sys/net/ipv4/tcp_fin_timeout
    60
    注意:这个参数在Linux中并非2MSL,而是fin-wait-2 状态超时时间。
    要调整TIME_WAIT参数,linux中需要修改内核宏定义重新编译,windows可以在注册表中修改。
    
    大家可以调整这个参数,然后再看Timer等待的时间。
    无论改成多少,笔者测试还是从60秒开始计时。
    
    netstat -ntpo 查看timer值
    
    • TCP其他参数优化项
    
    TCP 接收和发送缓冲区大小的默认值和最大值
    net.core.wmen_default
    net.core.wmen-max
    net.core.rmem_default
    net.core.rmem-max
    
    TCP保活机制 (以下数值单位均为秒)
    
    TCP保活机制中发送探测报文前的空闲时间
    cat /proc/sys/net/ipv4/tcp_keepalive_time
    7200(默认)
    
    TCP保活机制中连续发送探测报文的间隔时间
    cat /proc/sys/net/ipv4/tcp_keepalive_intvl
    30(默认)
    
    TCP保活机制中发送探测报文的次数
    cat /proc/sys/net/ipv4/tcp_keepalive_probes
    9(默认)
    
    net.ipv4.tcp_keepalive = 120
    net.ipv4.tcp_keepalive_intval = 30
    net.ipv4.tcp_keepalive_probes = 3
    
    • 汇总优化项目
    注意:以下内容仅为笔者总结,并未全部长期测试,建议自测后使用。
    汇总所有优化项目 ==> 个人虚拟机食用
    vi /etc/sysctl.conf
    
    # 超时重传的次数 ==> 建议减少重试次数, 以太网环境下
    net.ipv4.tcp_syn_retries = 3
    net.ipv4.tcp_synack_retries = 3
    
    # 队列满员情况下处理机制 ==> 建议保持默认
    net.ipv4.tcp_abort_on_overflow = 0
    
    # 半、全连接队列大小设置 ==> 建议适当增大
    net.ipv4.tcp_max_syn_backlog = 1024
    net.core.somaxconn = 1024
    
    # 默认就开启的  ==>非外层设备也可以考虑关闭
    net.ipv4.tcp_syncookies = 1
    
    # 快速回收连接 ==> 建议减少超时时间
    net.ipv4.tcp_fin_timeout = 30
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1
    
    # tcp 心跳保持 ==> 纯TCP服务建议调整
    net.ipv4.tcp_keepalive = 120
    net.ipv4.tcp_keepalive_intval = 30
    net.ipv4.tcp_keepalive_probes = 3
    
    # time wait 保持个数 ==> 建议适当增大
    net.ipv4.tcp_max_tw_buckets = 30000 
    
    sysctl -p
    

    相关文章

      网友评论

          本文标题:Linux TCP优化

          本文链接:https://www.haomeiwen.com/subject/maouydtx.html