吞吐测试基础:从一次线上事故说起
我记得那是某个电商大促的前夜。系统压测到凌晨三点,QPS 刚冲到 2000,响应时间就开始飙红线。老板站在身后问:「到底能扛多少?」我盯着监控屏,一句话都答不上来。
从那以后,我养成了一个习惯——任何系统上线前,必须先搞清楚它的吞吐天花板在哪。说白了,吞吐测试就是给你的系统做一次「体能测试」。你不知道它能跑多快、能扛多重,就敢让它上线?
吞吐量:单位时间内系统能处理的请求总数。它直接决定了你的服务能服务多少用户、能赚多少钱。
为什么吞吐量这么重要?
你想想看,一个电商网站每秒只能处理 100 个订单,但双十一流量来了每秒 10000 个请求——会发生什么?
- 用户体验崩塌:页面转圈、下单失败、支付超时
- 收入直接损失:每慢 100ms,转化率下降 7%(亚马逊的经典数据)
- 系统雪崩风险:请求堆积导致资源耗尽,最终整个服务挂掉
我在项目中遇到过最惨的一次:一个支付接口,平时 QPS 只有 500,上线前没做吞吐测试。结果活动当天流量冲到 3000,数据库连接池直接打满,所有请求排队等待,RT 从 50ms 飙到 30 秒。最后不得不手动重启服务,损失了将近两个小时的交易量。
血的教训:吞吐测试不是「有空再做」的事。它是系统上线的准入条件,没有吞吐数据的系统,就像没有刹车就上路的车。
核心指标:三个数字看懂系统性能
吞吐测试绕不开三个核心指标。我习惯把它们叫做「性能三剑客」:
| 指标 | 全称 | 一句话解释 | 我常用的关注点 |
|---|---|---|---|
| QPS | Queries Per Second | 每秒查询数 | 读接口、搜索接口最看重这个 |
| TPS | Transactions Per Second | 每秒事务数 | 写接口、下单支付这类完整事务 |
| RT | Response Time | 响应时间 | 用户体验的直接体现,我一般看 P99 |
嗯,这里要注意一个常见的误区:很多人把 QPS 和 TPS 混着用。其实它们有本质区别——QPS 侧重单次查询,TPS 侧重完整事务。一个下单接口,可能包含 3 次查询 + 1 次写入,TPS 是 100,但 QPS 可能是 400。
我的习惯:压测时同时监控 QPS 和 RT。如果 QPS 上去了但 RT 也大幅上涨,说明系统已经在「硬扛」了,这时候的 QPS 数据没有意义。
测试环境搭建:别在「假环境」上浪费时间
搭建吞吐测试环境,我踩过太多坑了。最典型的一次:在开发环境压测,QPS 轻松到 5000,美滋滋上线。结果生产环境连 2000 都扛不住——开发环境的数据库是单机,生产是主从;开发网络延迟几乎为零,生产要过三层交换机。
所以,环境搭建有几个硬性要求:
- 硬件配置与生产一致:CPU、内存、磁盘类型,能一样就一样
- 网络拓扑尽量仿真:至少保证网络延迟在同一数量级
- 数据量级接近真实:100 条数据和 1000 万条数据,数据库表现天差地别
- 独立压测机器:不要在压测目标机器上跑压测工具,会互相干扰
我个人习惯用 Locust 做压测工具。Python 写脚本,上手快,分布式也方便。下面是一个最基础的压测脚本:
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
wait_time = between(1, 3) # 模拟用户思考时间
@task
def index_page(self):
self.client.get("/")
@task(3)
def search_product(self):
self.client.get("/search?q=手机")
启动命令也很简单:
locust -f locustfile.py --host=https://your-api.com --web-port=8089
然后打开浏览器访问 http://localhost:8089,设置并发用户数和 spawn rate,就能看到实时数据了。
避坑指南:我曾经在压测时忘记设置 wait_time,结果所有请求瞬间发出,把测试环境打挂了。记住——压测要模拟真实用户行为,不是洪水攻击。
一张图看懂本章知识体系
下面这张图,把吞吐测试的核心逻辑串起来了:
本章小结
吞吐测试不是什么高深的技术,但它决定了你的系统能走多远。记住三个核心指标:QPS 看查询能力、TPS 看事务能力、RT 看用户体验。环境搭建别偷懒,工具选自己顺手的就行。
我见过太多团队,上线前不做吞吐测试,出了问题才手忙脚乱。别让这种事发生在你身上。