Tomcat部署的WAR包应用服务突然访问很卡,重启WAR包后才解决

1、问题前端用户突然使用系统非常卡,直至不能使用,也不报错,查看CPU,CPU Interrupt Time 百分之70多持续半小时,

2、在这半小时过程中,集中报错为:

        1、org.apache.catalina.connector.ClientAbortException: java.io.IOException: 断开的管道

        2、Caused by: org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer

3、查询数据库awr报告基本正常,没有大占用CPU的sql,基本正常,暂时排除数据库问题

     GC基本也是正常,没有FULLGC,也可以排除一些内存泄漏问题,只能怀疑Tomcat线程池了

4、tomcat线程号目测最大也才 [http-nio-50603-exec-118],目测线程池没满, 但是其中还有一些自定义线程 :[WhifExecutor-9] 这种线程

怀疑1:

  1. 外部服务调用阻塞

    • WhifExecutor-9这类线程表明应用可能使用了自定义线程池调用外部服务(如HTTP API、RPC、文件存储服务等)

    • 外部服务响应变慢或阻塞,导致Tomcat工作线程被挂起,最终客户端超时断开(触发Connection reset

    • 特征:卡顿时,线程dump会显示大量线程阻塞在外部调用(如HTTP连接、JDBC驱动等

5、看调用外部接口基本都是HTTP请求,tomcat线程发起,也就调用了五六次,每次调用基本卡4分钟,

 线程编号≠活跃线程数
  • Tomcat的线程编号是顺序递增但不连续

  • 线程复用机制可能导致编号停留在较低数值(如118),即使实际活跃线程数已经达到瓶颈

怀疑已经到达瓶颈了,WhifExecutor-9线程 等自定义线程池可能已耗尽(比如核心线程10个,队列100,但外部服务阻塞导致所有线程卡死)

最可能的罪魁祸首

外部服务阻塞 + 无超时设置 + 线程池隔离缺失的三重组合

  • 即使只有5-6个请求调用4分钟慢接口:

    • 占用5-6个Tomcat线程

    • 可能占满WhifExecutor自定义线程池(如核心线程5个)

    • 触发客户端重试制造更多请求

    • 最终导致健康检测、监控等基础请求也无法响应

为什么重启能临时解决?

重启后:

  1. 所有阻塞线程被强制终止

  2. TCP连接重置

  3. 线程池回到初始状态

虽然线程池物理隔离,但可能通过以下方式间接影响Tomcat性能:

关联场景影响机制
竞争CPU资源自定义线程池消耗大量CPU时,Tomcat线程无法获得足够计算资源

总结:

所以基本上:tomcat发起得外部服务阻塞+上自定义线程池竞争CPU导致,tomcat线程池即使没满,tomcat也没有cpu时间片去从线程池中拿线程,导致服务卡、宕机

CPU竞争引发卡顿的核心原理

1. 操作系统级线程调度
  • 所有线程(包括Tomcat和自定义线程)共享CPU时间片

  • 当自定义线程池(如WhifExecutor)的线程疯狂占用CPU时:

    • Tomcat线程虽然存在于线程池中

    • 无法获得足够的CPU时间片执行任务

    • 表现为请求响应延迟甚至超时

自定义线程池行为对Tomcat的影响
执行CPU密集型计算Tomcat线程被"饿死",无法处理简单HTTP请求
无节制的死循环整个应用失去响应(包括健康检查接口)
大量上下文切换CPU忙于切换线程,实际吞吐量下降

核心证据:从日志中看有6个慢请求

  1. TCP连接耗尽

    • 每个慢请求保持TCP连接4分钟(240秒)

    • 客户端端口复用周期通常为60-120秒(Linux默认)

    • 6个慢请求 × 240秒 = 需要至少1440个临时端口
      (超过默认net.ipv4.ip_local_port_range范围)

  2. 客户端重试风暴

    • 慢请求客户端超时后自动重试(如Nginx默认60秒超时)

    • 产生指数级新请求6请求 × 每60秒重试 × 4分钟 = 至少24次额外请求

  3. 负载均衡器踢节点

    • 健康检查失败(因为部分请求超时)

    • 流量转移到其他节点 → 剩余节点压力更大 → 雪崩


数学证明卡顿必然发生

使用**利特尔法则(Little's Law)**计算:

并发请求数 = 到达率 × 平均响应时间
  • 慢请求:6个 × 240秒 = 1440并发占用

  • 正常请求:100个/秒 × 0.05秒 = 5并发占用
    总计:1440 + 5 = 1445 >> 200(max-threads

👉 即使只有6个慢请求,实际并发需求远超线程池容量!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值