
Docker环境Spring Boot应用undertow大量http请求超时
发布日期:2021-05-16 22:38:38
浏览次数:20
分类:精选文章
本文共 1801 字,大约阅读时间需要 6 分钟。
Docker环境下Spring Boot应用undertow大量http请求超时问题
背景
项目采用Spring Cloud微服务架构,每个微服务都是一个Spring Boot应用。
- 项目使用嵌入式Web容器undertow进行http接口的相互通讯。
- 服务部署在阿里云容器服务(AliCloud Container Service,ACS)上。
- Spring Boot版本为1.5.9.RELEASE。
- Undertow版本为1.4.21.Final。
问题
某个关键微服务接口出现大量超时请求,严重影响系统正常运营。
定位过程
发现一:性能日志异常
通过查看超时请求的运行日志,发现以下警告日志:
timerCache is above the warning threshold of 1000 with size 2312
- 问题分析:
- 2312的位置数字逐渐增加,没有下降趋势。
- 与之前日志对比,今天的警告日志数量明显增加。
- 关联性分析:
- 该日志来自
org.springframework.cloud.netflix.metrics.servo.ServoMonitorCache
类的getTimer
方法。 - 该类与RestTemplate相关服务监控有关。
- 结合当前微服务大量使用RestTemplate进行http请求,初步怀疑是RestTemplate导致的性能问题。
- 该日志来自
解决尝试一:禁用Servo监控
在微服务的yml文件中添加配置:
spring: metrics: servo: enabled: false
- 实施方法:
- 尝试通过
/refresh
接口动态刷新配置,但发现配置无法生效。 - 问题根源在于
ServoMetricsAutoConfiguration
仅在启动时生效。
- 尝试通过
- 最终结果:
- 重启微服务后,警告日志消失,表明配置生效。
- 但未能解决http请求超时问题,仍需进一步排查。
发现二:JVM内存与GC问题
- 问题分析:
- 观察微服务的容器内存使用情况,发现JVM内存使用正常。
- 使用
jstat -gcutil PID 1s
监控GC情况,发现YGC(Young Generation Collection)每隔10秒执行一次,未见异常。
- 异常现象:
- 调用方报告5秒超时,而此微服务记录显示请求进入后10多秒才输出日志。
- 初步怀疑是请求进入队列排队,导致超时及日志延迟输出。
发现三:undertow线程配置不足
- 线程池状态:
- 通过Spring Boot Admin查看线程堆栈,发现此微服务仅有16个
XNIO-2-task
工作线程。 - 大部分线程处于
waiting
状态,少部分阻塞于业务逻辑处理。
- 通过Spring Boot Admin查看线程堆栈,发现此微服务仅有16个
- 负载分析:
- 16个工作线程远远不足以处理当前的请求量。
- 不时的线程阻塞导致服务响应变慢,甚至达到超时。
- 服务状态:
- Spring Boot Admin显示此微服务时而在线,时而离线(离线原因是
/health
接口超时)。
- Spring Boot Admin显示此微服务时而在线,时而离线(离线原因是
解决方法
配置线程池参数
在微服务的yml文件中增加以下配置:
server: undertow: io-threads: 16 worker-threads: 256
- 实施效果:
- 重启微服务后,观察到http请求超时问题得到有效缓解。
- 服务状态在Spring Boot Admin中保持稳定在线。
结论
原因分析
- 问题根源:
- undertow的默认工作线程配置不足,无法处理大量的并发http请求。
- 16个工作线程在高并发场景下显然无法满足需求,导致请求排队和超时。
扩展思考
常见问题与解决方案
Web应用大量http请求超时
- 检查Web容器配置:确保工作线程数量和队列大小适当。
- 监控Web容器状态:关注线程池的活跃状态、排队请求数等关键指标。
容器级监控
- 使用工具(如Prometheus + Grafana)对Web容器进行全面监控,包括CPU、内存、线程池状态等。
- 若有需要,可开发自定义监控组件,实时追踪关键指标。
###疑问解答
默认配置:
- Undertow默认工作线程配置较为保守,以确保兼容性和稳定性。
- 如果其他微服务未做线程池调整,可能是因为其业务需求较低或使用模式不同。
线程配置为何选择256:
- 根据实际负载测试结果,确定最小需要256个工作线程以满足高并发需求。
- 可通过负载测试模拟大量请求,动态调整线程池参数。
发表评论
最新留言
哈哈,博客排版真的漂亮呢~
[***.90.31.176]2025年04月15日 20时50分35秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Linux kernel pwn --- CSAW2015 StringIPC
2019-03-12
配置jdk的环境变量
2019-03-12
编译android源代码(aosp)
2019-03-12
IDEA 找不到 Persistence窗口解决办法
2019-03-12
维基百科之AndroidRoot
2019-03-12
C++ Primer Plus读书笔记:循环读取(错误处理)
2019-03-12
skimage与cv2 安装失败的解决办法
2019-03-12
关于吴恩达的深度学习的一些授课视频里面英文翻译错误的实例展示
2019-03-12
伴随矩阵和逆矩阵的关系证明
2019-03-12
突破Bias-Variance困境
2019-03-12
Form窗体属性
2019-03-12
解决宝塔安装wordpress无法连接到数据库问题
2019-03-12
解决Eclipse加载图片或网页出现404错误
2019-03-12
vue 错误收集
2019-03-12
Java选择排序算法实现
2019-03-12
00010.02最基础客户信息管理软件(意义类的小项目,练习基础,不涉及数据库)
2019-03-12
00013.05 字符串比较
2019-03-12
LeetCode: 138. 复制带随机指针的链表(中等)[DFS, 迭代]
2019-03-12
Effective Java 读书笔记
2019-03-12