• TCP高并发连接异常


    FIN_WAIT状态

             

            FIN_WAIT状态分析

                 注意到FINWAIT-2这个状态,它的转移条件只有一个,即收到对端的FIN,然后进入TIME_WAIT.收到对端的FIN之前,本端会一直保持FINWAIT-2状态

                TCP是一个双向全双工的传输协议,本端发送FIN仅仅意味着本端到对端这个方向上的传输结束了,而对端到本端的传输依然可以继续,直到对端也发送一个FIN过来.所以说我们看到断开连接的挥手动作是4次,其实就是两个来回,每一个来回关闭一个方向的数据传输

               如果对端故意不发送FIN,且也不传输数据,那么意味着本端始终处在FINWAIT-2状态而资源无法释放,这是一个DDoS的典型场景

               连接在FINWAIT-2超时后并不会进入TIMEWAIT状态,也不会发送reset,而是直接默默消失

              由图可以看出是远程连接的主机没有及时发送FIN状态位给本机,导致本机无效连接占用过多资源.客户端已经没有能力继续回复ACK,造成了服务器端大量的端口处在FIN_WAIT_2状态,不能释放

     解决方案

    net.ipv4.tcp_fin_timeout = 10
    net.ipv4.tcp_keepalive_time = 30
    net.ipv4.tcp_window_scaling = 0
    net.ipv4.tcp_sack = 0 
    View Code

          调整内核参数解决
          vi /etc/sysctl.conf
          

         编辑文件,加入以下内容:
          net.ipv4.tcp_syncookies = 1
          net.ipv4.tcp_tw_reuse = 1
          net.ipv4.tcp_tw_recycle = 1
          net.ipv4.tcp_fin_timeout = 30

         执行/sbin/sysctl -p让参数生效

          net.ipv4.tcp_syncookies = 1表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
          net.ipv4.tcp_tw_reuse = 1表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
          net.ipv4.tcp_tw_recycle = 1表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
          net.ipv4.tcp_fin_timeout修改系統默认的TIMEOUT时间

          发现大量的TIME_WAIT 已不存在,mysql进程的占用率很快就降下来的,网站访问正常。
          不过很多时候,出现大量的TIME_WAIT状态的连接,往往是因为网站程序代码中没有使用mysql.colse(),才导致大量的mysql  TIME_WAIT.

          

          进入TIME_WAIT状态的一般情况下是客户端,大多数服务器端一般执行被动关闭,不会进入TIME_WAIT状态,当在服务器端关闭某个服务再重新启动时,它是会进入TIME_WAIT状态的。

         1.客户端连接服务器的80服务,这时客户端会启用一个本地的端口访问服务器的80,访问完成后关闭此连接,立刻再次访问服务器的80,这时客户端会启用另一个本地的端口,而不是刚才使用的那个本地端口。原因就是刚才的那个连接还处于TIME_WAIT状态。

         2.客户端连接服务器的80服务,这时服务器关闭80端口,立即再次重启80端口的服务,这时可能不会成功启动,原因也是服务器的连接还处于TIME_WAIT状态。

          netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

         

        集群各个节点之间的网络通信恢复正常

    TIME WAIT状态

          

         主动关闭的一方会进入TIME_WAIT状态,并且在此状态停留2MSL时长
         TIME_WAIT的产生条件:主动关闭方在发送四次挥手的最后一个ACK后会变为TIME_WAIT状态,持续时间为2MSL
         一个TCP/IP连接断开以后,会通过TIME_WAIT的状态保留一段时间,时间过了才会释放这个端口,当端口接受的频繁请求数量过多的时候,就会产生大量的TIME_WAIT状态的连接,这些连接占着端口,会消耗大量的资源

         如果你的连接数本身就很多,我们可以再优化一下TCP/IP的可使用端口范围,进一步提升服务器的并发能力。依然是往上面的参数文件中,加入下面这些配置:

         net.ipv4.tcp_keepalive_time = 1200
         net.ipv4.ip_local_port_range = 10000 65000
         net.ipv4.tcp_max_syn_backlog = 8192
         net.ipv4.tcp_max_tw_buckets = 5000

        这几个参数,建议只在流量非常大的服务器上开启,会有显著的效果。一般的流量小的服务器上,没有必要去设置这几个参数。这几个参数的含义如下:
        net.ipv4.tcp_keepalive_time = 1200 表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。
        net.ipv4.ip_local_port_range = 10000 65000 表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为10000到65000。(注意:这里不要将最低值设的太低,否则可能会占用掉正常的端口!)
       net.ipv4.tcp_max_syn_backlog = 8192 表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
       net.ipv4.tcp_max_tw_buckets = 5000 表示系统同时保持TIME_WAIT的最大数量,如果超过这个数字,TIME_WAIT将立刻被清除并打印警告信息。默认为180000,改为5000

  • 相关阅读:
    小孩补脑 微信公众号
    学习用具汇总 微信公众号
    多带小孩去的地方 微信公众号
    PHP如何开启opcache缓存
    clip命令
    git pull push 报错 no matching host key type found. Their offer sshrsa
    生信分析 | 哲学方法论
    深入浅出Nginx实战与架构
    YCFramework版本更新:V1.0.7
    我的学习方法论
  • 原文地址:https://www.cnblogs.com/yxh168/p/16423823.html
Copyright © 2020-2023  润新知