记一次springBoot内置tomcat最大线程数导致的接口超时问题

现象描述:

服务早高峰时大量接口耗时激增最慢时达到20-30秒响应。且并非个别接口,而是所有接口都有超时现象,最终排除了机器与代码逻辑的问题,修改了springBoot内置tomcat的配置使现象好转。

经后续排查。最开始只有主页接口有超时现象,随后的两分钟所有的接口都产生了超时现象。

排查:

一.查看超时接口的代码,有逻辑复杂的也有逻辑简单的纯内存操作的,理论上不可能同时出现超时。查看了接口内方法的耗时,都在几毫秒。

  • 接口耗时日志通过过滤器进行打印。显示耗时为10秒-30秒。

  • 通过skywalking查看接口内部方法的耗时,都是简单的redis操作,耗时为几毫秒,但是最终的接口耗时达到28秒。

  • 相同的接口在相同的时间有超时的有不超时的,且每个不同的接口都有这种现象。

二.综上所述排除了接口本身的问题,把排查目标转移到jvm和机器cpu,内存上

  • 机器cpu:正常

  • 机器内存:正常

  • 网络请求数:为突然增多

解决:

一. 基本确定是由于突然增大的流量导致的,此时想到应该是springBoot内置的tomcat容器配置问题导致的

  • 但是请求数增多为什么会导致接口响应时长变长?查看了springBoot项目的tomcat配置没有配置,所以使用的是默认配置。

  • 查看springqBoot tomcat配置类:ServerProperties.Tomcat.maxThreads 默认配置为200个线程,即服务的线程超过200个时会进行等待。

  • 超时的时间段是流量高峰,有一个外部接口的调用时长较高,平均响应时长在15秒以上,导致tomcat线程池中的线程无法释放,新来的请求就会等待,1分钟后外部接口熔断现象自动好转了。

结论:

  • 早高峰时由于运营推送短信,造成较多用户同时访问主页接口,主页接口内通过http调用了一个第三方提供的接口,该接口响应非常慢,再该时间段平均响应时长在15秒左右。导致了tomcat中有大量的活跃线程无法释放。

  • 在流量高峰期我们的服务cpu与内存都属于健康状态,说明服务器性能并没有瓶颈,接口响应慢是因为新的请求在等待tomcat线程池中的线程释放。适当增加tomcat线程池maxThreads的数量便可在不影响服务器性能的情况下减少接口响应时间,即让单机可并行处理更多请求。

  • 查看了高峰期单机的活跃线程数为500个左右,远大于了tomcat默认的200个,所以将maxThreads设置为600

  • 当然影响本次故障的主要原因并不是最大线程数问题,正常情况下200个线程是足够的,主要原因为我们的服务调用的第三方接口响应太慢,没有及时熔断引起了雪崩效应,如果用户请求不断增多,第三方接口一直阻塞。那么无论maxThreads是多少都会被打满,只有解决第三方接口响应慢才能根本的解决问题,方法有:

  • 找第三方接口的开发人员沟通让他们降低自己接口响应时间(显然不可能)

那么就只能从自身做改变了:

  1. 熔断平均耗时较高的第三方接口,并设计降级方案

  1. 根据经验设置请求三方接口的超时时间,不要无限等待

  1. 对自己服务的接口进行限流

application.yml文件中增加如下配置

server:
  port: 8080
  tomcat:
    max-threads: 600 #默认为200 我的机器是4核8g,根据压测结果设置为600

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值