Docker环境Spring Boot应用undertow大量http请求超时

Docker环境Spring Boot应用undertow大量http请求超时

背景

  • 项目采用Spring Cloud微服务架构,每个微服务都是一个Spring Boot应用。
  • undertow做嵌入式Web容器,http接口相互通讯。
  • 使用阿里云容器服务部署在Docker环境。
  • Spring Boot版本——1.5.9.RELEASE
  • undertow版本——1.4.21.Final

问题

一个关键微服务接口出现大量超时,严重影响系统正常运营。

定位过程

发现一

查看某个超时请求运行日志,发现一条Warn级别日志:timerCache is above the warning threshold of 1000 with size 2312

  • 2312位置数字只增不减
  • 今天这种日志的数量明显比前几天多很多

日志是org.springframework.cloud.netflix.metrics.servo.ServoMonitorCache类getTimer方法输出。经查询,发现这个类是netflix的运行指标收集相关类。

有人发现它和RestTemplate出现服务不可用相关。参考
使用RestTemplate遇到线上的问题

结合自己这个微服务接口需要大量使用RestTemplate的情况,初步怀疑是这个问题。

解决办法:微服务yml文件增加spring.metrics.servo.enabled=false

最初,想利用actuator的/refresh接口动态刷新这个配置,这样不需要重启微服务。

  • refresh接口调用成功,但配置不生效。
    (后面发现,这个开关配置是决定是否执行某个Configuration的,只有启动时生效。
    具体见类org.springframework.cloud.netflix.metrics.servo.ServoMetricsAutoConfiguration)

接下来,只好重启微服务。

重启后,不再有上面的Warn日志输出,说明配置生效。但无法确定是否解决请求大量超时问题,只能继续观察。

不久,又出现大量http请求超时…

发现二

初步怀疑是不是应用JVM内存出现问题。

于是进入微服务的container,使用jstat -gcutil PID 1s观察一段时间,
发现除了YGC会每隔10s执行一次,其他区域及GC次数和时长都没有异常。
暂时无法确定每10s一次的YGC频率是否有问题,继续观察。

又查看一条调用超时请求,结合调用方和此微服务日志一起看,发现问题:
调用方5s超时,此微服务十多秒后才输出这次请求的入口日志。

首先,确定调用方和此微服务所在容器时间没有差异;那么,有个怀疑:是不是此微服务无法处理这么多请求,部分请求进入队列排队,导致请求超时且日志延时输出?

我们使用嵌入式Web容器undertow,没有做任何配置调整,也不太清晰undertow内部实现,初步推断它处理http请求也是采用线程池模式。

通过Spring Boot Admin查看此微服务的线程堆栈Threads,发现只有16个worker线程(XNIO-2-task开头),大部分处于waiting状态。

  • 虽然处于waiting状态的线程阻塞在JDK本身的LockSupport.park方法,少部分阻塞于业务逻辑;但结合这个微服务承载的请求量,16个worker线程肯定是不够的。
  • 同时,我发现此微服务在Spring Boot Admin上的状态是时而在线,时而离线(离线是因为请求/health接口超时)。

结合上面情况,基本确定是undertow工作线程不足导致问题。

解决方法:yml文件增加

server:
  undertow:
    io-threads: 16
    worker-threads: 256

重启微服务。观察一段时间,没有再出现http请求超时,问题解决。

结论

undertow的工作线程不足,导致大量http请求超时。

拓展

1、遇到web应用大量http请求超时,应该首先检查Web容器的配置及负载情况。
2、Web容器作为web应用的核心组件,应该加上监控,方便查看Web容器状态(总线程数、当前正在处理请求数、排队请求数等)。后续查找或自写一个监控组件。

疑问

undertow的默认配置是怎样的?为什么其他微服务也没配置参数,有256个工作线程?

疑问已有解答,精彩待续…

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值