性能测试疑问:SpringBoot REST API仅返回空串时为何TPS随并发增加逐步骤降?
异常性能问题定位:SpringBoot极简GET接口并发下逐步劣化
已观测到的反常压测现象
- 原依赖外部服务调用的GET接口:常规压测阶段TPS全程保持稳定,仅响应时间随并发数升高线性变长,无性能急剧劣化表现,单接口响应时延稳定在300-400ms
- 改造为无外部依赖、仅返回空字符串的基线对照接口后:单请求响应时延从300-400ms降至30ms,相同并发量级下TPS较原接口大幅提升
- 基线接口异常表现:无法长时间支撑10以上的并发负载,当并发用户数超过10时,哪怕仅执行无业务逻辑的空返回请求,系统性能也会随运行时间逐步劣化,最终趋近于不可用
该行为是否属于正常情况
完全不属于正常的SpringBoot Web服务运行表现。正常内嵌Tomcat/Jetty容器承载的无业务逻辑空返回GET接口,单实例支撑百级并发、毫秒级响应是基础能力,仅10并发就出现随运行时间逐步劣化的情况,必然存在资源泄漏、配置硬限制或观测偏差。
高概率的异常原因方向
- Web容器线程池配置不合理:比如内嵌Tomcat的最大工作线程数被手动设置为过低值,且未配置合理的请求队列缓冲策略,导致请求排队、线程上下文切换开销随运行时间累积
- TCP连接资源耗尽:未开启客户端与服务端的Keep-Alive连接复用机制,大量TCP连接处于TIME_WAIT状态,随运行时间累积占满操作系统端口表或进程文件句柄数,导致新连接无法正常建立
- JVM层面资源泄漏:空接口虽无业务逻辑,但框架层的切面、拦截器逻辑在每次请求时持续创建对象、持有静态引用,短时间压测下触发频繁GC、堆内存持续上涨,挤占请求处理资源
- 磁盘IO瓶颈:应用开启了高频率的访问日志、框架调试日志,压测产生的大量日志持续写入磁盘,随磁盘队列长度累积,IO等待时间持续升高,最终拖慢整体请求处理能力
- 压测客户端侧的瓶颈假象:压测工具自身未配置连接池复用机制,单并发下持续创建新线程、新连接,自身资源耗尽后表现为服务端性能劣化的观测假象
问题定位的采集与调试手段
- 全链路基础运行指标采集
- 操作系统层监控:使用
top、vmstat、ss -ant、lsof、iostat -xmt 1监控CPU使用率、内存占用、TCP连接状态分布、文件句柄占用量、磁盘IO利用率,快速定位是CPU打满、内存泄漏、端口/句柄耗尽还是IO瓶颈 - JVM运行监控:使用
jstat -gcutil <pid> 1000按1秒间隔监控GC频率、各内存代的占用变化,发现内存泄漏时使用jmap -dump:live,format=b,file=heap.bin <pid>导出堆快照分析异常对象引用链 - Web容器层监控:开启SpringBoot Actuator的容器指标端点,查看Tomcat工作线程池活跃数、请求队列积压数、累计处理请求数、错误请求数的变化曲线
- 操作系统层监控:使用
- 控制变量分步验证
- 从1并发开始逐步提升负载到15并发,记录系统从正常运行到出现劣化的时间拐点,对应匹配前述监控指标的变化节点,缩小问题排查范围
- 切换不同的压测工具、调整压测端的连接超时与复用配置,排除客户端自身瓶颈导致的观测偏差
- 手动调整Tomcat最大线程数、队列长度、操作系统文件句柄上限等参数做对照实验,验证配置限制类问题
- 深层问题定位
- 开启请求链路埋点,统计每次请求的全流程耗时分布,确认请求是卡在网络接入层、容器排队层还是业务执行层
- 在系统出现性能劣化时,使用
jstack <pid>导出全量线程栈,分析所有工作线程的阻塞状态,排查是否存在锁等待、资源争用类问题
内容的提问来源于stack exchange,提问作者TrollBearPig
相关产品推荐
相关产品推荐

