首页
首页
文章目录
  1. 简介
  2. 名词解释
  3. 命令
    1. ESTABLISHED
    2. TIME_WAIT
    3. CLOSE_WAIT

关于服务器出现的TIME_WAIT和CLOSE_WAIT的原因以及解决方法

简介

今天遇到一个问题,就是我们跑在容器里面的某个服务挂了,健康检查无限重启服务,而且很奇怪,服务刚刚启动成功的时候,监控检查页面是正常的,过个2、3分钟后,页面就超时,无法打开了。而且 程序运行日志也无任何异常。

现象大致就这些,然后开始看了下并发心态崩了,ESTABLISHED的只有20来个,但是 CLOSE_WAIT有8800多个。预计问题就是因为CLOSE_WAIT太多导致服务问题处理不过来,从而导致服务异常。

名词解释

TCP连接中有以下三个主要的名词ESTABLISHED、CLOSE_WAIT、TIME_WAIT

名词解释 名词解释

命令

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

ESTABLISHED

ESTABLISHED 表示已经建立连接,三次握手成功,数据正在通信。

如服务器中出现ESTABLISHED连接数过多,解决方法只有一个,增加机器配置,增加机器数量。通过增加硬件方式来解决。

TIME_WAIT

TIME_WAIT 表示主动关闭,三次握手中,服务端已经发起关闭连接,还会受到对方的响应。

当服务器出现TIME_WAIT连接数过多,这个可以通过修改系统参数配置来让服务器能够快速回收和重用那些TIME_WAIT的资源。

修改参数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# vim /etc/sysctl.conf
#对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃,不应该大于255,默认值是5,对应于180秒左右时间
net.ipv4.tcp_syn_retries=2
#net.ipv4.tcp_synack_retries=2
#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为300秒
net.ipv4.tcp_keepalive_time=1200
net.ipv4.tcp_orphan_retries=3
#表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间
net.ipv4.tcp_fin_timeout=30  
#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_syn_backlog = 4096
#表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭
net.ipv4.tcp_syncookies = 1
#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭
net.ipv4.tcp_tw_reuse = 1
#表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭
net.ipv4.tcp_tw_recycle = 1
#减少超时前的探测次数 
net.ipv4.tcp_keepalive_probes=5 
#优化网络设备接收队列 
net.core.netdev_max_backlog=3000

之后执行sysctl -p让参数生效。

net.ipv4.tcp_tw_reuse和net.ipv4.tcp_tw_recycle的开启都是为了回收处于TIME_WAIT状态的资源。
net.ipv4.tcp_fin_timeout这个时间可以减少在异常情况下服务器从FIN-WAIT-2转到TIME_WAIT的时间。
net.ipv4.tcp_keepalive_*一系列参数,是用来设置服务器检测连接存活的相关配置。

CLOSE_WAIT

CLOSE_WAIT 表示被动关闭,如网络异常,如服务未响应等。

CLOSE_WAIT出现的情况需要先描述下:服务器A是一台爬虫服务器,它使用简单的HttpClient去请求资源服务器B上面的apache获取文件资源,正常情况下,如果请求成功,那么在抓取完资源后,服务器A会主动发出关闭连接的请求,这个时候就是主动关闭连接,服务器A的连接状态我们可以看到是TIME_WAIT。如果一旦发生异常呢?假设请求的资源服务器B上并不存在,那么这个时候就会由服务器B发出关闭连接的请求,服务器A就是被动的关闭了连接,如果服务器A被动关闭连接之后程序员忘了让HttpClient释放连接,那就会造成CLOSE_WAIT的状态了。

总结:
所以如果将大量CLOSE_WAIT的解决办法总结为一句话那就是:查代码。因为问题出在服务器程序里头啊。

以上
End!

支持一下
扫一扫,我会更有动力更新
  • 微信扫一扫
  • 支付宝扫一扫