一、问题的本质
问:要求吞吐量达到200,并发至少是多少?
这是一个典型的性能测试面试题。正确的回答是:这个问题没有固定答案,因为缺少最关键的自变量------平均响应时间(RT)。
二、核心公式:利特尔定律(Little's Law)
在性能测试中,吞吐量(TPS)和并发数之间的关系可以用利特尔定律来描述:
并发数 = 吞吐量 × 平均响应时间
或者写成:
吞吐量 = 并发数 ÷ 平均响应时间
2.1 公式各参数含义
| 参数 | 含义 | 单位 |
|---|---|---|
| 并发数 | 系统同时处理的请求/事务数 | 个 |
| 吞吐量 | 单位时间内完成的事务数 | TPS(事务/秒) |
| 平均响应时间 | 完成一个事务所用的平均时间 | 秒 |
2.2 公式推导
如果系统在1秒内完成了N个事务,平均每个事务耗时T秒,那么系统中同时存在的事务数为:
text
并发数 = N × T = 吞吐量 × 平均响应时间
三、不同场景下的并发数估算
假设目标吞吐量为200 TPS,不同平均响应时间下所需的并发数:
| 平均响应时间 | 计算公式 | 所需并发数 | 场景说明 |
|---|---|---|---|
| 0.1秒(100ms) | 200 × 0.1 | 20 | 接口极快,纯内存操作 |
| 0.2秒(200ms) | 200 × 0.2 | 40 | 高性能接口 |
| 0.5秒(500ms) | 200 × 0.5 | 100 | 普通业务接口典型值 |
| 1秒 | 200 × 1 | 200 | 中等复杂业务 |
| 2秒 | 200 × 2 | 400 | 复杂业务,含DB写操作 |
关键结论 :响应时间越长,需要的并发数就越大。没有"至少多少",只有"至少 = 200 × 平均RT"。
四、JMeter中的实际操作
4.1 标准操作流程(三步走)
Step 1:摸底响应时间
先用10个线程,不加任何吞吐量定时器,跑1分钟,查看聚合报告中该事务的平均响应时间(Average)。
Step 2:套公式计算并发数
text
并发数 = 200 × 平均响应时间(秒)
假设测出来平均响应时间 = 0.3秒,则:
text
并发数 = 200 × 0.3 = 60个线程
Step 3:设置并验证
-
在JMeter线程组中设置线程数为60(或稍微多点做冗余,如70)
-
添加
常数吞吐量定时器(Constant Throughput Timer),目标吞吐量填12000(因为单位是请求/分钟,200 × 60 = 12000) -
运行测试,观察实际TPS是否稳定在200附近
4.2 使用精确吞吐量定时器
如果使用Precise Throughput Timer,可以直接设置目标吞吐量为200,单位选择"请求/秒"。
4.3 重要注意事项
线程数必须足够:设置的线程数必须大于或等于理论计算出的最小并发数,否则定时器也无法"无中生有"地达到目标吞吐量。
五、常见误区
5.1 误区一:把"并发数"和"线程数"划等号
在JMeter中,一个线程确实模拟一个用户,但:
-
线程数 = 你设置的并发用户数
-
实际服务器承受的并发 = 线程数 × (1 - 思考时间占比)
5.2 误区二:把"响应时间"和"思考时间"搞混
如果事务控制器里加了思考时间(Think Time),公式中的平均响应时间要变成:
text
有效响应时间 = 接口响应时间 + 思考时间
例如:接口响应0.5秒 + 思考2秒 = 2.5秒,则并发数 = 200 × 2.5 = 500个线程。
5.3 误区三:盲目增加并发数
这个公式成立的前提是系统未达到性能瓶颈。如果数据库连接池、网络带宽等资源已耗尽,盲目增加并发用户,吞吐量不但不会提升,反而可能下降。
六、面试回答话术
如果别人问你这个问题,可以这样回答:
"这个问题无解 ,因为缺少最关键的自变量------平均响应时间(RT) 。并发和吞吐量不是直接画等号的,它们之间遵循利特尔定律:
并发数 = 吞吐量 × 平均响应时间
假设平均响应时间是0.5秒,那并发至少需要100个;如果是1秒,就需要200个。响应时间越长,需要的并发数就越大。
所以,在不考虑响应时间的前提下谈并发,都是耍流氓。 给我平均RT,我就能给你精确的并发数。"
七、总结
| 关键点 | 内容 |
|---|---|
| 核心公式 | 并发数 = 吞吐量 × 平均响应时间 |
| 无固定答案 | 取决于平均响应时间 |
| 操作流程 | 先摸底RT → 套公式算并发 → 设置定时器验证 |
| 常见误区 | 忽略思考时间、盲目增加并发 |
一句总结:并发数没有固定值,完全取决于接口的平均响应时间。并发数 = 200 × 平均RT,先测RT,再算并发。