当前位置: 首页 > 质量专栏 > 软件压力测试TPS、QPS无法达标主要原因与优化
软件压力测试TPS、QPS无法达标主要原因与优化
2026-05-09 作者cwb 浏览次数34

压力测试TPS/QPS不达标是系统容量在某个步骤遇到了短板。要解决这个问题不能靠盲猜调参,需要系统化地逐层排查。


一、快速自查压测本身是不是合理

在怀疑系统前,先排除压测工具的干扰,避免测不准。

压测机资源是不是打满:单台施压机受限于带宽、CPU和端口数,如果CPU使用率超过90%或网络流量接近上限,增加并发产生的不是真实吞吐。这时需增加压测机数量或将工具改为分布式运行。

连接和超时配置:检查压测客户端的HTTP连接池大小、连接超时、响应超时是不是过短,导致请求堆积在客户端而不是服务端。

模拟是不是真实:如果压测脚本请求参数过于单一,所有请求都命中一条缓存数据,测出的TPS看似很高但无法代表真实场景,也可能导致缓存命中率高假象,业务数据读盘就会垮掉。必须使用数据参数化模拟真实分布。


二、定位问题从资源到代码

确定压测本身无问题就沿着网络-主机资源-应用服务-中间件-数据库这条链路排查。


1. 网络和带宽问题

现象:TPS达到一定值后完全平直,增加并发也不上升,且服务端CPU、内存使用率都很低。

排查:检查压测机和服务器之间的带宽,或后端服务间的内网带宽是不是占满。云服务器一般有带宽上限(如5Mbps),计算:1000个100KB响应体请求,理论QPS上限仅(带宽×1024/8)/ 100 ≈ 6.4,远远拖垮目标。

优化:升级带宽,开启Gzip压缩缩小响应体,使用CDN分流静态资源,减少不必要的大报文传输。


2. 服务端硬件资源问题

通过 top、vmstat、dstat、云监控等观察四个标准:


CPU:

CPU使用率高(>85%):一般是代码思路复杂、序列化开销大、频繁GC、正则一致过多等。需用Profiler工具定位热点方法。

CPU使用率低但TPS上不去:问题多数在阻塞等待(等待锁、IO、数据库响应),线程都处于BLOCKED或WAITING状态,CPU自然空闲。


内存:

内存不足导致频繁GC,尤其是Full GC耗时数秒,会暂停所有用户线程,TPS瞬间跌零,出现毛刺。需检查JVM堆配置和内存泄漏。


磁盘IO:

磁盘IO高(util接近100%)会导致写日志、读配置、数据库落盘都变慢。如果应用日志级别为DEBUG或数据库随机IO过多,TPS必受影响。


网络连接数和端口:

服务端单机端口范围有限(约28000+),高并发短连接下可能导致TIME_WAIT堆积,新连接无法建立。需优化为长连接或调整内核参数。


3. 应用服务层问题


线程池/连接池配置过小:

Web容器(Tomcat/Jetty)最大工作线程数、数据库连接池、Redis连接池、HTTP客户端连接池等,任何一个配置小于并发量都会让请求排队等待。

测试:看线程dump,如果大量线程在 getConnection() 等待,即数据库连接池不够。


锁竞争严重:

同步块过大、全局锁、分布式锁等待超时,导致大量线程串行执行。

现象:TPS无法随并发数线性增长,大量线程处于BLOCKED状态。


阻塞式IO或长耗时外部调用:

一个请求内同步调用了多个外部HTTP接口、发送邮件等,耗尽容器线程。必须用异步化、MQ解耦。

不合理的超时和重试:

超时设得过长,线程被慢请求长时间占用;重试次数过多,下游一慢导致上游雪崩。


4. 数据库层问题

数据库一般是最后一道关,也是最大的问题。


慢SQL和缺失索引:

explain 查看执行计划,是不是全表扫描、索引未命中、临时表排序过大。

高并发下,一条慢SQL每秒被执行上百次就会拖垮整个库。


连接数不足:

数据库最大连接数有限(如MySQL默认151),连接池总连接数超过上限或配置过低都会阻塞。


锁冲突:

行锁等待:大量更新同一条记录(如扣减库存),或间隙锁导致插入阻塞。要分析SHOW ENGINE INNODB STATUS,优化事务模型,将热点行分散或使用队列串行化。


事务范围过大:

把RPC调用、文件操作置于事务内,导致长事务锁定资源,阻塞后续事务。


缓存无法扛量:

没有缓存或缓存透过,全部请求直接打到数据库,数据库很快CPU或磁盘IO打满。


5. 中间件和架构问题

负载不均衡:各服务器压力差别大,某个实例先达到短板。

消息队列积压:消费者处理能力不足,消息堆积,TPS体现在异步链路上减弱。

缓存击穿/雪崩:热点Key失效瞬间,大量请求涌向数据库。

序列化/反序列化:使用了低效序列化协议(如Java原生序列化),或JSON反序列化大对象耗时高。

三、系统优化方法

1. 应用层优化

扩容线程池/连接池:根据实测并发数调整Tomcat最大线程数(如从200扩至500)、数据库连接池(如HikariCP的maximumPoolSize)。但要结合硬件,避免过高导致上下文切换剧增。

异步化改造:对于非即时响应必须完成的操作(发短信、记录日志、推送),使用MQ异步处理,缩短主链路响应时间,释放线程。

减少锁粒度:用ConcurrentHashMap替代Hashtable,用分段锁,或在数据库方面用乐观锁替代悲观锁。

本地/分布式缓存:热点数据使用Caffeine、Redis缓存,设置合理的淘汰时间和预热方法。

代码级微优化:避免大循环中字符串+拼接,降低序列化开销(使用Protobuf),使用连接池化复用。


2. 数据库优化

SQL优化和索引:这是性价比最高的,一个缺少索引的SQL优化后QPS可能提升百倍。

读写分离:主库写,从库读,分摊压力。

分库分表:单表数据量过大或写入热点时,横向拆分。

批量操作:将单条插入改为批量插入,减少和数据库的交互次数。

调整事务隔离级别:在保证业务正确情况下,读多写少场景可以用读提交,降低锁持有。


3. 系统和JVM层调优

JVM参数:选择合适的垃圾回收器(如G1),调大新生代,减少Full GC。合理设置-Xmx和-Xms。

内核参数:调整tcp_tw_reuse、tcp_fin_timeout快速回收TIME_WAIT连接;增大file-max和用户进程文件句柄数限制。

启用压缩:Nginx/网关开启Gzip,缩小网络传输量。


4. 架构扩展

水平扩容:增加服务节点,通过负载均衡分摊流量,这是提升容量上限的方法。

服务隔离:重要服务独立部署,避免被非重要服务拖累。

限流和熔断:防止突发流量打垮系统,保护下游。


四、定位工具

全局监控(Grafana+Prometheus/云监控):先看四大资源(CPU、内存、网络、磁盘),确定资源层是不是已到顶。

应用层剖析(Arthas/JProfiler/strace):CPU高则用thread -n 3看线程栈,抓热点方法;CPU低则dump线程,分析线程状态(WAITING还是BLOCKED),看他们在等什么锁或IO。

数据库审计(慢查询日志、performance_schema):抓Top慢SQL,分析执行计划和锁等待。

链路追踪(SkyWalking/Pinpoint):看一次请求耗时分布,定位是哪个服务或SQL慢。


性能优化是一个循环:设定目标-压测-监控定位-优化调整-回归压测。每次只改一个配置或代码,测试效果,不断逼近目标值。


文章标签: 压力测试 并发压力测试 测评网站并发压力
咨询软件测试