一次Tamcat无响应问题分析

问题描述

程序的架构是一个HTTP客户端的上报服务,一个HTTP服务端的接收服务,今天测试人员反映数据上报不上去了,请求全部失败

排查思路

1.查看客户端日志

发现所有的请求都是报错503,初步确定是服务端的问题,因为服务端使用了Zuul作为网关,503是我们自定义的超时状态码

2.查看网关Zuul的日志

发现在网关的断路器回调接口里面,报了大量的后端服务超时日志,确定是其中的一个物联平台服务,基本上hystrix的状态一直都是断开,直接返回的服务不可用。

3.登录eureka确定物联平台服务在哪台机器上

登录euraka,发现服务还在,确定服务的euraka心跳线程还活着,在euraka控制台找到出问题的服务的机器,登录这个机器排查原因

4.查看CPU和内存有没有大的波动

使用top命令和free命令,发现CPU和内存都挺稳定,排除了死循环

5.jps 查看java进程

jps的结果显示服务还在,并没有挂掉

6.查看出问题的服务的日志

发现只有eureka心跳打印的日志,猜测是其他线程被阻塞在某个资源上面了

7.jstack pid 查看线程快照

使用jstack pid > jstack.log把线程快照保存到文件,便于拿到本地分析,但是这个东西第一次接触,是在是看不出有什么问题,只是看到了存在大量的WAITING的线程,
在这里插入图片描述

8.jmap查看堆内存情况

使用jmap -heap pid命令查看堆内存,发现新生代Eden区占用90%,但是S0和S1基本上占用比较小,老年代占用40%多,确定不是内存溢出导致的
使用jstat -gc pid 2000 20每个两秒打印GC情况,一共打印20次,发现堆内各个区域都不满,但是也没有回收,(因为线程都阻塞了嘛,所有请求都进不来)

9.回光返照

其实到这里我已经没有思路了,感觉像是玄学一样,确定是线程被阻塞,我只能在回去看jstack.log文件,同时在网上查找这个文件能怎么用。忽然之间,我好像发现了一丝丝地异常
在这里插入图片描述
这个应该就是表示在8004这个端口上有很多的http线程处于WAITING状态,而8004端口上运行的恰好就是出问题的物联平台服务,到这里我忽然觉得问题明朗起来了,我想起来Tamcat有最大连接数这么一回事,在Spring boot里面貌似默认是200,那么问题是他为什么会被阻塞呢,是不是有的接口很慢???

再后来在网上看到可以使用netstat查看网络状态,于是使用netstat | grep pid,查看到在这个进程上确实有大量的连接,并且全部处于CLOSE_WAIT状态,细心的我会议起了TCP的三次握手和四次挥手
在这里插入图片描述
由上图可以看到,CLOSE_WAIT状态是客户端发起第一次挥手,向服务端发送FIN包,然后服务端向客户端发送ACK包,表示自己收到了断开连接的请求,但是自己还有数据没发送完(比如我服务里面哪个超时的接口),然后服务端就进入了CLOSE_WAIT状态,结果这个接口的响应时间实在是太长了,然后客户端等不及了,主动断开了连接,等到服务端终于执行完接口发送FIN包时,客户端早就把连接断开了,于是客户端回复的是一个RST包,表示我不认识你。

总结下来就是
在服务器与客户端通信过程中,因服务器发生了socket未关导致的CLOSE_WAIT发生,致使监听port打开的句柄数到了1024个,且均处于close_wait的状态,最终造成配置的port被占满出现“Too many open files”,无法再进行通信。

10.解决方案

出现这种问题基本上都是我们的程序的原因,解决方案有三步

  1. 修改超时的接口,优化代码逻辑,降低响应时间
  2. 设置服务端CLOSE_WAIT的超时时间
  3. 增大tamcat最大连接数
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值