服务器CLOSE_WAIT请求太多的问题

简介: 服务器CLOSE_WAIT请求太多的问题

上周因为调用某个服务不可用,导致服务器出现了大量的CLOSE_WAIT的tcp链接,导致tomcat出现了假死的情况.大量的tcp请求一直卡着,其他请求进来tomcat已经不能提供服务了.
头一次遇到这样的情况,然后查了一下这个CLOSE_WAIT的资料.发现CLOSE_WAIT其实是tcp的一种状态,我们先来看张图了解一下tcp的各个状态.

状态:
CLOSED: 没有任何连接状态,是tcp状态的起点和终点(这时候服务器啥都没干)
LISTEN: 监听来自远方的TCP端口的连接请求
SYN_SENT: 第一次收到请求的状态,由客户端发送给服务端,成功后进入到SYN_RECEIVED,失败的直接CLOSED
SYN_RECEIVED:再收到和发送一个连接请求后等待对方对连接请求的确认
ESTABLISHED: 三次握手完成,已经简历一个打开的连接,这个时候就可以发送数据了
FIN_WAIT_1: 等待远程TCP连接中断请求,或先前的连接中断请求的确认
FIN_WAIT_2: 接受了远端的ACK确认之后,从等待连接中断请求
CLOSE_WAIT: 等待从本地用户发来的连接中断请求
CLOSING: 等待远程TCP对连接中断的确认
LAST_ACK: 等待原来的发向远程TCP的连接中断请求的确认
TIME_WAIT: 等待足够的时间以确保远程TCP接收到连接中断请求的确认

对照着客户端和服务端的状态变化来理解消化下

问题分析:

看完上面tcp的各个状态变化过程之后,应该有了一个大致的了解 ,给我们看下服务器上的tcp请求状态情况,可以使用命令

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

当时检测出来CLOSE_WAIT 大概有1000左右,这个和httpClient设置的maxConnTotal的数量查不多.

tcp请求关闭包含主动关闭和被动关闭,当服务端收到了中断的seq和ack后,就处于CLOSE_WAIT状态,
,照理说应该立马发送ack.但是处于CLOSE_WAIT说明服务端没有发送ack到客户端(其实这里实际上是远端服务端).导致这种情况的可能是
服务端忙于处理数据或者是其他操作,导致没有发出去ack命令.

我检查了发送请求的代码response等流都是正常关闭了,那么我们看下是不是其他问题导致,发现当接收到响应的时候,如果状态不是200,请求就直接返回了.大概类似于这样:

if (response.getStatusLine() == HttpStatus.SC_OK) {
 // 具体处理
}

如果不等于200的情况没有处理,修改后

if (response.getStatusLine() == HttpStatus.SC_OK) {
 // 具体处理
} else {
  httpRequest.abort();
 // 中断状态不对的请求
}

然后我们在etc/sysctl.conf加上如下三个参数:
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 2
net.ipv4.tcp_keepalive_time = 1800 // 单位是秒 就是30分钟

然后sysctl -p让配置生效.

1.tcp_keepalive_time
当keepalive起用的时候,TCP发送keepalive消息的频度,就是说空闲这个时间然后去确认连接是否还在,缺省是2小时。
2.tcp_keepalive_intvl
当探测没有确认时,重新发送探测的频度。缺省是75秒。
3.tcp_keepalive_probes
在认定连接失效之前,发送多少个TCP的keepalive探测包

我只做了这两个操作就CLOSE_WAIT数量就下来了,还有其他可能性也会导致这样的情况.可以参考下面的资料

参考资料:

1.https://www.cnblogs.com/jessezeng/p/5616518.html
2.https://blog.csdn.net/shootyou/article/details/6615051

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
7月前
|
监控 Java 应用服务中间件
低并发编程|如何用720个请求让后端服务器瘫痪
本次故障因应用启动时未有效校验核心依赖模块初始化异常,导致后续请求处理中抛出无法捕获的错误,引发线程阻塞,最终耗尽HSF线程池,服务不可用。排查发现类初始化失败且异常未被正确处理,结合线程无限等待问题,确认为依赖初始化异常与流处理中断所致。修复措施包括加强启动校验、捕获Throwable及设置合理超时。总结指出,系统稳定性需从细节入手,防微杜渐,避免连锁故障。
低并发编程|如何用720个请求让后端服务器瘫痪
|
10月前
|
JSON API 数据安全/隐私保护
使用curl命令在服务器上执行HTTP请求
总的来说,curl是一个非常强大的工具,它可以让你在命令行中发送各种类型的HTTP请求。通过学习和实践,你可以掌握这个工具,使你的工作更加高效。
954 30
|
Swift iOS开发
iOS Swift使用Alamofire请求本地服务器报错-1002
iOS Swift使用Alamofire请求本地服务器报错-1002
410 1
|
开发框架 缓存 .NET
并发请求太多,服务器崩溃了?试试使用 ASP.NET Core Web API 操作筛选器对请求进行限流
并发请求太多,服务器崩溃了?试试使用 ASP.NET Core Web API 操作筛选器对请求进行限流
558 0
|
Linux
【Linux】一条命令,转发所有请求到另一台服务器上 -高级技巧
【Linux】一条命令,转发所有请求到另一台服务器上 -高级技巧
210 0
|
JSON JavaScript 前端开发
《进阶篇第6章:vue中的ajax》包括回顾发送ajax请求方式、vue-cli脚手架配置代理服务器、vue-resource
《进阶篇第6章:vue中的ajax》包括回顾发送ajax请求方式、vue-cli脚手架配置代理服务器、vue-resource
222 22
|
前端开发 JavaScript Java
第6章:Vue中的ajax(包含:回顾发送ajax请求方式、vue-cli脚手架配置代理服务器)
第6章:Vue中的ajax(包含:回顾发送ajax请求方式、vue-cli脚手架配置代理服务器)
311 4
|
前端开发 Java
学习SpringMVC,建立连接,请求,响应 SpringBoot初学,如何前后端交互(后端版)?最简单的能通过网址访问的后端服务器代码举例
文章介绍了如何使用SpringBoot创建简单的后端服务器来处理HTTP请求,包括建立连接、编写Controller处理请求,并返回响应给前端或网址。
434 0
学习SpringMVC,建立连接,请求,响应 SpringBoot初学,如何前后端交互(后端版)?最简单的能通过网址访问的后端服务器代码举例
|
开发者
HTTP状态码是由网页服务器返回的三位数字响应代码,用于表示请求的处理结果和状态
HTTP状态码是由网页服务器返回的三位数字响应代码,用于表示请求的处理结果和状态
383 1
|
存储 运维 Java
函数计算产品使用问题之如何使用Python的requests库向HTTP服务器发送GET请求
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
301 8

热门文章

最新文章