服务器TPS过低,根因多半不在服务器本身,而是卡在数据库、代码逻辑或Full GC上。这是排查时的第一判断,能帮你少走半天弯路,下面按问题出现频率从高到低,把常见原因和对应解法一次说清。
数据库成了拖后腿的瓶颈
TPS上不去,十次里有八次是数据库先扛不住,应用服务器计算再快,数据读写卡住,整个链路照样转不动。
慢查询吃掉了大部分时间片
单条查询耗时过长,是TPS上不去的头号嫌疑犯。 业务逻辑里藏着几条没走索引的SELECT,平时数据量小没感觉,等用户量一上来,每条请求都卡在数据库上,TPS自然直线往下掉。
排查时先打开慢查询日志:
- MySQL执行
SET GLOBAL slow_query_log = ON;,并设置long_query_time = 1,把超过1秒的语句记录下来。 - 拿到慢SQL后,用
EXPLAIN看执行计划,重点检查type列是不是ALL(全表扫描)或key列为空(没走索引)。 - 为高频查询的
WHERE条件字段建立联合索引,注意字段顺序,区分度高的放前面。
业内专家指出,大多数慢查询通过合理索引就能解决,真正需要改表结构的场景占比很小。
连接池被打满,请求排队干等
TPS不高,但连接池监控显示活跃连接数顶满,请求全在等待获取连接,这往往是连接泄漏或池大小配置不合理。
- 检查代码里有没有
Connection未关闭的情况,用try-with-resources或finally块确保释放。 - 连接池大小不是越大越好。MySQL默认连接数上限151,连接池设太大会反过来拖垮数据库。
- 按公式估算:
连接数 = 核心数 × 2 + 有效磁盘数,Tomcat默认200,一般业务50到100足够。
缓存没命中,压力全打给数据库
Redis缓存命中率低,热点数据每次都穿透到MySQL,监控上表现为数据库QPS很高,但TPS就是上不去。

解决办法分三步:
- 先用
INFO stats查看keyspace_hits和keyspace_misses,算出命中率。 - 命中率低于90%时,检查缓存key的设计是否合理,过期时间是否太短。
- 对热点key做多级缓存,本地Caffeine加分布式Redis,扛住大部分读请求。
应用层代码拖慢处理速度
数据库没问题时,问题就出在应用自己的代码上。
同步调用太多,线程全在阻塞等待
一个请求链路里串了三次远程调用,每个都等500毫秒,整体耗时1.5秒,TPS自然上不去。把同步改异步,是提升TPS最立竿见影的手段之一。
- 用户下单后,发短信、加积分、更新推荐池这些操作,全部丢进MQ异步处理。
- 用
CompletableFuture并行调用多个无依赖的RPC接口,把串行时间压到最长的那个。 - 设置合理的线程池大小,参考公式:
线程数 = CPU核心数 × (1 + 等待时间 / 计算时间)。
线程池参数胡乱配,资源浪费或耗尽
线程池设置过小,请求排队;设置过大,CPU频繁上下文切换,TPS反而下降,这在压测时特别明显,线程数翻倍,TPS曲线不升反降。
行业共识认为,线程池大小需要压测来确定,不要拍脑袋。 从核心数 × 2开始,逐步加压,观察TPS和RT的拐点。
Full GC频繁,应用卡在垃圾回收上
GC日志里Full GC次数每分钟超过一次,就要警惕TPS被垃圾回收拖垮。 表现为TP99突刺明显,接口偶尔卡顿几秒。
排查路径:
- 用
jstat -gcutil <pid> 1000观察GC频率,重点看FGC列。 - 配合
jmap -dump:live,format=b,file=heap.bin <pid>导出堆,用MAT分析大对象。 - 常见问题是大对象直接进老年代,或
ConcurrentHashMap
缓存无界限膨胀。
- 调优时优先调
-Xmx和-XX:NewRatio,必要时换G1收集器。
服务器硬件资源到底够不够
代码和数据库都查过没问题,再回头看机器本身。
CPU使用率虚高还是实高
top命令看CPU,us(用户态)高说明业务代码在疯狂计算,sy(内核态)高说明频繁系统调用或线程切换。
- CPU跑满但TPS低,多半是代码里有死循环或正则回溯。
- CPU空闲但TPS低(“服务器tps低什么原因”常见场景),那问题在锁竞争或远程调用等待上。
- 用
jstack抓线程快照,连续抓三次,看线程卡在哪个状态。
磁盘IO成为隐形瓶颈
TPS要求高时,磁盘读写跟不上,尤其日志写到同一块盘,和数据库抢IO。
- 用
iostat -x 1看%util,超过80%说明磁盘繁忙。 - 把日志和应用分盘存放,用SSD替代机械盘,随机读写性能提升几个量级。
- 落盘方式从同步刷盘改成异步批量写,或直接上Kafka扛日志。
架构层面还有哪些坑
单机优化到极限还是不够,就得从架构上找空间。
单点部署,资源天花板明显
一台8核16G的机器,TPS上限大概在几千到一万。只要流量再涨,单点物理瓶颈就卡死TPS。
- 应用做水平扩展,前面挂Nginx或SLB负载均衡。
- 无状态服务多部署几台,数据库用读写分离扛读压力。
- 实例多了之后,注意连接数是否被打满。
远程调用链路长,RT积少成多
一个下单接口依赖库存、优惠券、用户、支付四个服务,每个接口平均50毫秒,四个串下来就200毫秒,加上业务自身逻辑,TPS很难上去。
用Arthas的trace命令定位链路里最慢的环节,逐个优化。解决“服务器tps太低怎么办”这类问题,核心就一句话:把最耗时的环节找出来,并行化或削峰。

压测时TPS数据要怎么看
排查完原因,压测验证是检验成效的唯一标准。
| 指标 | 正常范围 | 异常表现 |
|---|---|---|
| 数据库慢查询 | 无超过1秒的SQL | 有则先优化索引 |
| GC频率 | Full GC每小时个位数 | 每分钟都有则堆内存异常 |
| 线程池活跃度 | 小于池大小80% | 长期100%且队列堆积 |
| 磁盘IO | 使用率低于60% | 持续高于80%需升级硬件 |
压测工具推荐wrk或JMeter,从低并发开始逐步加压,记录TPS和RT曲线。TPS峰值出现在并发数某个临界点,过了这个点TPS下降,说明资源已耗尽,不是压测工具的问题。
常见问题汇总
服务器TPS过低和CPU使用率高有关系吗
通常有关系,CPU被计算密集型操作占满时,处理请求的能力下降,TPS随之下滑,但也存在CPU空闲而TPS低的情况,此时问题大多出在数据库锁等待、远程调用超时或线程池阻塞上。
服务器TPS低如何排查
按三层顺序来:先看数据库慢查询和连接池,再看应用GC和线程池,最后查服务器CPU、磁盘和网络,每层都用对应工具取数,不要凭感觉猜。
MySQL慢查询会影响TPS吗
影响很大。 慢查询会占用数据库连接,连接耗尽后所有请求都排队等待,TPS整体被拉低,开启慢查询日志,找到执行时间最长的SQL,用EXPLAIN分析执行计划,针对性地加索引或改写SQL。
排查TPS问题,坚持从数据库到代码再到硬件的顺序,用数据说话而不是靠猜。根因找到后,TPS提升往往立竿见影慢查询优化索引能恢复大部分性能,Full GC调优能让接口延迟回归正常。 按上面步骤走一遍,多数场景都能在半小时内定位。
图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/895695.html

