4、 TPS(每秒事务数)指标:别被数字骗了

讲到TPS,我得先给你泼盆冷水。我见过太多团队,压测报告上TPS写着5000,上线当天系统就挂了。为什么?因为他们连“事务”的边界都没搞清楚。

TPS这三个字母,核心在“T”。T理不顺,后面的P和S就是空中楼阁。今天咱们就把“事务”这两个字掰开揉碎,讲明白。

4.1 事务的原子性定义:到底什么算“一个”事务?

“原子性”这个词,搞技术的都听过。但放到接口压测里,它有个非常具体的定义:一次从用户视角出发的、完成完整业务动作的请求-响应过程。

举个例子。你去银行APP转账。

  • 错误的定义:调用了一次转账接口,算1个事务。
  • 正确的定义:从你点击“转账”,到APP提示“转账成功”,到后台完成扣款、通知收款方、记录流水,再到你能看到余额更新。这一连串动作,才算1个事务。

你想想看,这个区别在哪?原子性不是“接口调一次”,而是“业务完成一次”。

核心原则: 事务的原子性由业务语义决定,而非接口数量。

我在项目中遇到过最典型的例子。一个下单接口,压测时单接口TPS能到3000。但一加上库存扣减、优惠券核销、积分计算这几个下游调用,整个链路的TPS直接掉到800。为什么?因为单接口的事务定义太“瘦”了。

这里给你一个判断标准:

  • 简单事务:一次HTTP请求=一次业务动作。比如查询天气、获取验证码。
  • 复合事务:一次业务动作=多次内部调用。比如下单、支付、退款。

嗯,这一点不搞清楚,后面的TPS计算全是错的。

4.2 TPS与QPS的区别:别再混为一谈了

我面试过不少人,一问TPS和QPS的区别,答案清一色:“TPS是每秒事务数,QPS是每秒查询数。” 这么说没错,但太笼统了。用起来就乱套。

说白了,区别就在于“复杂度”。

指标 核心含义 典型场景 计算粒度
QPS 每秒请求/查询次数 读多写少、缓存穿透、静态资源 单次网络请求
TPS 每秒完整事务数 核心交易、写操作、复杂链路 完整业务动作

为什么需要区分?我举个例子。

一个用户登录场景。登录接口调用一次,返回。这是1个QPS。但登录这个“事务”可没完,它可能包括:验证密码、下发、记录登录日志、更新用户最后在线时间。如果这些都在一个接口里完成,那1个QPS≈1个TPS。但如果验证密码和记录日志是分开的两个接口调用,那1个TPS就变成了2个QPS。

你看,差别就在这里。

避坑指南: 我曾经在一个广告推荐项目中,团队拿着QPS 5000的报告来汇报,结果一细看,每次广告点击需要调3次接口。实际TPS才1600多。差点上线,真悬。

我个人的习惯是:

  • 选QPS:当接口是纯粹的信息查询,不涉及写数据或状态变化时。
  • 选TPS:当接口涉及核心业务链路,有写操作、状态机变更、跨服务调用时。

别纠结字面,要看你压测的目标是什么。如果是评估系统容量,我建议统一用TPS。因为TPS更能反映系统处理真实业务的吞吐能力。

4.3 复杂事务场景下的TPS计算:别再用简单平均了

好了,最难的部分来了。单个接口的TPS好算,总请求数除以时间就行。但复杂事务场景下,整个链路串起来,TPS怎么算?

直接给你公式?不行。咱们先看场景。

场景一:串联事务(A依赖B,B依赖C)

这是最常见的情况。比如一个下单流程:网关验签 → 订单服务 → 扣库存 → 发消息。

每个环节都有独立的处理时间。整个链路的TPS受限于最慢的那个环节。这就像一条流水线,速度由最慢的工位决定。

总TPS = 1 / (T1 + T2 + T3 + ... + Tn)

其中Tn = 每个环节的平均处理时间(秒)

举个例子。验签耗时10ms,订单处理50ms,扣库存20ms,发消息5ms。总耗时 = 10+50+20+5 = 85ms。那这个链路的理论最大TPS = 1 / 0.085 ≈ 11764。

看到没?不是单个接口能扛多少QPS,而是整条链路的耗时加起来决定了最终TPS。

场景二:并联事务(A同时依赖B和C)

系统里也经常有这种操作:用户注册后,同时发短信和邮件。这两个任务互不依赖,可以并行。

总TPS = 1 / max(T1, T2, T3, ..., Tn)

取最慢的那个并行支路的时间

发短信30ms,发邮件80ms。那整体耗时取最大值80ms。理论最大TPS = 1 / 0.08 = 12500。

这就是为什么我会在压测脚本里使用多线程发送并发请求,就是为了把并联的耗时压到最低。

场景三:混合依赖(有串有并)

现实里都是这种。我建议你先画出依赖图,拆解成串行阶段和并行阶段,再合并计算。

我通常的做法: 先用XMind或纸笔画出业务链路的依赖关系。串联部分相加,并行部分取最大值。然后两者再相加,得到单事务的端到端耗时。最后用1除以这个耗时,得到TPS上限。

这里还有一个公式,很多书上不写,但我认为非常实用:

TPS = (并发线程数 * 事务数) / 压测时长

但别忘了关联资源利用率:
TPS = min( 带宽限制, CPU核心数 * 请求处理速率, 数据库连接池 / 平均事务耗时 )

嗯,最后这个公式,你在压测结果分析时,一定要自己算一遍。我曾经在一个项目里,压测发现TPS上不去,排查一圈发现是数据库连接池不够。池子从100扩到300,TPS直接翻倍。

讲到底,TPS不能光看数字大小,要结合事务的复杂性来看。同样是5000 TPS,一个纯缓存查询的场景和一个跨5个微服务的交易场景,系统的实际承载力天差地别。

我的经验: 压测报告里TPS要注明事务的“重量”。比如“当前TPS 2000(单事务涉及3次RPC调用+1次DB写入)”。这样别人才能看懂这个TPS的分量。

最后,给你一个实用提醒。复杂场景下计算TPS,别忘了回放时间。你的压测脚本里,think time、思考时间、异步回调的等待时间,都会影响真实TPS。我习惯的做法是,先不加think time压一轮,拿到极限值。然后加上业务实际的等待时间,再压一轮,拿到真实值。对比两个值,你就能知道系统“理论能扛多少”和“实际能扛多少”的差距。

TPS 核心知识体系 事务原子性定义 简单事务 vs 复合事务 TPS 与 QPS 核心区别 复杂场景 TPS 计算 串联 TPS 公式 并联 TPS 公式 混合依赖拆解 实践要点:识别依赖关系 → 选择计算模型 → 关联资源利用率 → 设置合理Think Time 提示:串联用加法(耗时累加),并联用最大值(耗时取Max),混合场景先拆解再合并