根据TCP/IP介绍,socket大概包含10个连接状态。我们平常工作中遇到的,除了针对SYN的拒绝服务攻击,如果有异常,大概率是TIME_WAIT和CLOSE_WAIT的问题。TIME_WAIT一般通过优化内核参数能够解决;CLOSE_WAIT一般是由于程序编写不合理造成的,更应该引起开发者注意。

TIME_WAIT

TIME_WAIT是主动关闭连接的一方保持的状态,像nginx、爬虫服务器,经常发生大量处于time_wait状态的连接。TCP一般在主动关闭连接后,会等待2MS,然后彻底关闭连接。由于HTTP使用了TCP协议,所以在这些频繁开关连接的服务器上,就积压了非常多的TIME_WAIT状态连接。

某些系统通过dmesg可以看到以下信息。

__ratelimit: 2170 callbacks suppressedTCP: time wait bucket table overflowTCP: time wait bucket table overflowTCP: time wait bucket table overflowTCP: time wait bucket table overflow

通过ss -s命令查看,可以看到timewait已经有2w个了。

ss -sTotal: 174 (kernel 199)TCP:   20047 (estab 32, closed 20000, orphaned 4, synrecv 0, timewait 20000/0), ports 10785

sysctl命令可以设置这些参数,如果想要重启生效的话,加入/etc/sysctl.conf文件中。

# 修改阈值net.ipv4.tcp_max_tw_buckets = 50000 # 表示开启TCP连接中TIME-WAIT sockets的快速回收net.ipv4.tcp_tw_reuse = 1#启用timewait 快速回收。这个一定要开启,默认是关闭的。net.ipv4.tcp_tw_recycle= 1   # 修改系统默认的TIMEOUT时间,默认是60snet.ipv4.tcp_fin_timeout = 10

测试参数的话,可以使用 sysctl -w net.ipv4.tcp_tw_reuse = 1 这样的命令。如果是写入进文件的,则使用sysctl -p生效。

CLOSE_WAIT

CLOSE_WAIT一般是由于对端主动关闭,而我方没有正确处理的原因引起的。说白了,就是程序写的有问题,属于危害比较大的一种。

Socket中的11种状态

1、客户端独有的:(1)SYN_SENT (2)FIN_WAIT1 (3)FIN_WAIT2 (4)CLOSING (5)TIME_WAIT 。2、服务器独有的:(1)LISTEN (2)SYN_RCVD (3)CLOSE_WAIT (4)LAST_ACK 。3、共有的:(1)CLOSED (2)ESTABLISHED 。各个状态的意义如下: LISTEN - 侦听来自远方TCP端口的连接请求; SYN-SENT -在发送连接请求后等待匹配的连接请求; SYN-RECEIVED- 在收到和发送一个连接请求后等待对连接请求的确认; ESTABLISHED- 代表一个打开的连接,数据可以传送给用户; FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;FIN-WAIT-2 - 从远程TCP等待连接中断请求; CLOSE-WAIT - 等待从本地用户发来的连接中断请求; CLOSING -等待远程TCP对连接中断的确认; LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认; TIME-WAIT -等待足够的时间以确保远程TCP接收到连接中断请求的确认; CLOSED - 没有任何连接状态;

我们平常工作中遇到的,除了针对SYN的拒绝服务攻击,大概率是TIME_WAIT和CLOSE_WAIT的问题。

TIME_WAIT一般通过优化内核参数能够解决。

CLOSE_WAIT一般是由于程序编写不合理造成的,更应该引起开发者注意。

1. time_wait状态如何产生? 调用close()发起主动关闭的一方,在发送最后一个ACK之后会进入time_wait的状态,也就说该发送方会保持2MSL时间之后才会回到初始状态。MSL值得是数据包在网络中的最大生存时间。产生这种结果使得这个TCP连接在2MSL连接等待期间,定义这个连接的四元组(客户端IP地址和端口,服务端IP地址和端口号)不能被使用。

2.time_wait状态产生的原因

1)为实现TCP全双工连接的可靠释放

假设发起主动关闭的一方(client)最后发送的ACK在网络中丢失,由于TCP协议的重传机制,执行被动关闭的一方(server)将会重发其FIN,在该FIN到达client之前,client必须维护这条连接状态,也就说这条TCP连接所对应的资源(client方的local_ip,local_port)不能被立即释放或重新分配,直到另一方重发的FIN达到之后,client重发ACK后,经过2MSL时间周期没有再收到另一方的FIN之后,该TCP连接才能恢复初始的CLOSED状态。如果主动关闭一方不维护这样一个TIME_WAIT状态,那么当被动关闭一方重发的FIN到达时,主动关闭一方的TCP传输层会用RST包响应对方,这会被对方认为是有错误发生,然而这事实上只是正常的关闭连接过程,并非异常。

2)为使旧的数据包在网络因过期而消失

为说明这个问题,我们先假设TCP协议中不存在TIME_WAIT状态的限制,再假设当前有一条TCP连接:(local_ip, local_port, remote_ip,remote_port),因某些原因,我们先关闭,接着很快以相同的四元组建立一条新连接。本文前面介绍过,TCP连接由四元组唯一标识,因此,在我们假设的情况中,TCP协议栈是无法区分前后两条TCP连接的不同的,在它看来,这根本就是同一条连接,中间先释放再建立的过程对其来说是“感知”不到的。这样就可能发生这样的情况:前一条TCP连接由local peer发送的数据到达remote peer后,会被该remot peer的TCP传输层当做当前TCP连接的正常数据接收并向上传递至应用层(而事实上,在我们假设的场景下,这些旧数据到达remote peer前,旧连接已断开且一条由相同四元组构成的新TCP连接已建立,因此,这些旧数据是不应该被向上传递至应用层的),从而引起数据错乱进而导致各种无法预知的诡异现象。作为一种可靠的传输协议,TCP必须在协议层面考虑并避免这种情况的发生,这正是TIME_WAIT状态存在的第2个原因。

3)总结 具体而言,local peer主动调用close后,此时的TCP连接进入TIME_WAIT状态,处于该状态下的TCP连接不能立即以同样的四元组建立新连接,即发起active close的那方占用的local port在TIME_WAIT期间不能再被重新分配。由于TIME_WAIT状态持续时间为2MSL,这样保证了旧TCP连接双工链路中的旧数据包均因过期(超过MSL)而消失,此后,就可以用相同的四元组建立一条新连接而不会发生前后两次连接数据错乱的情况。

通过ss -s命令查看,可以看到timewait已经有2w个了。

如果想要重启生效的话,加入/etc/sysctl.conf文件中。

net.ipv4.tcp_syncookies = 1  #表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;net.ipv4.tcp_max_tw_buckets = 50000 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 = 10  # 修改系统默认的TIMEOUT时间,默认是60s

使用sysctl -p生效

如果以上配置调优后性能还不理想,可继续修改一下配置:

vi /etc/sysctl.confnet.ipv4.tcp_keepalive_time = 1200 #表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。net.ipv4.ip_local_port_range = 1024 65000 #表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。net.ipv4.tcp_max_syn_backlog = 8192 #表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。net.ipv4.tcp_max_tw_buckets = 5000  #同时保持TIME_WAIT套接字的最大个数,超过这个数字那么该TIME_WAIT套接字将立刻被释放#并在/var/log/message日志中打印警告信息(TCP: time wait bucket table overflow)。#这个过多主要是消耗内存,单个TIME_WAIT占用内存非常小,但是多了就不好了,这个主要看内存以及你的服务器是否直接对外#默认为180000,改为5000。#对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量#但是对于 Squid,效果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。

CLOSE_WAIT

这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是查看你是否还有数据发送给对方,如果没有的话,那么你也就可以close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。CLOSE_WAIT一般是由于对端主动关闭,而我方没有正确处理的原因引起的。说白了,就是程序写的有问题,属于危害比较大的一种。代码需要判断socket,一旦读到0,断开连接,read返回负,检查一下errno,如果不AGAIN,就断开连接。

linux表示文件连接数,linux中连接数过多(TIME_WAIT/CLOSE_WAIT)读这一篇就够了相关推荐

  1. linux查看文件创建人,Linux中如何查看文件的创建时间详解

    一.简介 Linux的文件能否找到文件的创建时间取决于文件系统类型,在ext4之前的早期文件系统中(ext.ext2.ext3),文件的元数据不会记录文件的创建时间,它只会记录访问时间.修改时间.更改 ...

  2. linux去掉文件空行,linux下删除文件中空行的多种方法 互联网技术圈 互联网技术圈...

    源文件: $ cat a.txt baiked.com is a best Linux blog to learn Linux. It's FIVE years old blog. This webs ...

  3. Linux 执行文件 path,linux可执行文件添加到PATH环境变量的方法

    linux命令行下面执行某个命令的时候,首先保证该命令是否存在,若存在,但输入命令的时候若仍提示:command not found 这个时候就的查看PATH环境变量的设置了,当前命令是否存在于PAT ...

  4. linux 音频文件长度,Linux下压缩音频文件

    安装工具 sudo apt-get install lame 具体用法可以查看帮助  lame --help 通过更改音频文件的帧数 可以让文件变小  但是音质也会随之下降 现在比较多的mp3文件是1 ...

  5. linux传输文件无密码,Linux下scp无密码上传 下载 文件 目录

    在Linux下远程备份的时候,需要配置scp的 无密码复制文件.目录.就把这个设置整理如下: 本地服务器:A 远程服务器:B 1.在 A 上运行 :ssh-keygen -t rsa 在/root/. ...

  6. linux c文件操作,Linux C 文件的输入/输出操作

    10.1 文件I/O操作概述 在Linux系统中,文件I/O操作可以分为两类,一类是基于文件描述符的I/O操作,另一类是基于数据流的I/O操作. 10.1.1 文件描述符简介 在文件操作一章中,也经常 ...

  7. linux history文件路径,Linux、Unix常用命令(文件和目录相关)

    mkdir dirname 建立子目录. 注意:用户不能在一个不存在的目录中建立子目录. mkdir data 在当前目录下建立子目录 data mkdir /usr/data 在/usr/目录下建立 ...

  8. linux传文件file,linux文件的传输与压缩快速入门

    scp --- 用于远程拷贝文件 上传文件 scp file user@ip:/file 下载文件 scp user@ip:/file file rsync --- 远程同步,速度块,默认会忽略,文件 ...

  9. linux 查找文件 locate,linux文件查找(find,locate)

    文件查找: locate: 非实时,模糊匹配,查找是根据全系统文件数据库进行的: # updatedb, 手动生成文件数据库 速度快 find: 实时 精确 支持众多查找标准 遍历指定目录中的所有文件 ...

最新文章

  1. 一阶逻辑与二阶逻辑的区别一元谓词多元谓词
  2. Hi3516A开发--烧写/启动模式
  3. python找到一行单词中最长的_在Python的给定列表中找到k个最长的单词
  4. 使用maven时报错Dynamic Web Module 3.1 requires Java 1.7 or newe
  5. python pandas serie简介及基本使用
  6. linux下的各个语言中stdin,stdout和stderr理解
  7. 【Spark】Spark基本概念
  8. 【原】 图片预览 Image preview
  9. 17.1 Replication Configuration 复制:
  10. 百度ocr文字识别接口使用
  11. 队列加分项:杨辉三角
  12. Python爬虫学习简单入门(第四含scrapy安装)
  13. 原创玄幻小说--那时花开--第一章前序
  14. echarts地图功能实现及坐标定位
  15. win10升级系统版本的步骤,win10电脑如何升级系统版本
  16. 拓嘉辰丰电商:拼多多视频如何制作
  17. 英语3500词(十)adventure主题(2022.1.22)
  18. 数据结构-图(图的定义、分类、基本术语和存储结构)
  19. 报500服务器内部错误解决思路
  20. 怎样才能做好app应用推广?

热门文章

  1. P1035 [NOIP2002 普及组] 级数求和
  2. oracle 01031 dblink,通过修改基表(link$)让非public dblink变为public
  3. 问题:tomcat启动后,可以访问主页面,但是无法访问dubbo-admin
  4. 玩转MFC文档视图架构编程1——深入浅出MFC文档/视图架构之基本概念深入浅出MFC文档/视图架构之文档
  5. TS 类型备忘 音视频格式
  6. 软件测试就是挑Bug?也许你有认知偏差
  7. 网易2017实习生笔试6
  8. 游戏服务端框架之使用Redis实现跨服排行榜
  9. 拒绝背后黑手的窥探IPC$漏洞大揭秘
  10. 北京2022年高考数学题纯手工排版