2. 测试环境搭建:硬件选型与软件栈配置
环境搭建这事儿,说简单也简单,说复杂能让你折腾一礼拜。我见过太多团队,工具选得挺牛,脚本写得也挺花,结果一跑压测,瓶颈全在环境本身——说白了,你连个靠谱的“试验台”都没搭好,测出来的数据谁敢信?
这一章,我就把硬件选型、软件栈配置、压测工具选型这三块掰开揉碎讲清楚。你跟着我的思路走一遍,至少能少踩一半的坑。
2.1 硬件选型:别让机器拖了后腿
硬件选型有个核心原则:压测机的性能必须远高于被测系统。否则你测出来的不是系统瓶颈,而是压测机自己在喘。
2.1.1 CPU:核心数与频率的博弈
我个人习惯,压测机CPU至少8核起步,16核是标配。为什么?因为并发线程数通常要压到目标系统的2~3倍,核数不够,线程切换开销就能把CPU吃满。
| 场景 | 推荐CPU配置 | 说明 |
|---|---|---|
| 轻量接口压测(< 1000 QPS) | 4核8线程 | 单机JMeter即可 |
| 中等规模(1000~10000 QPS) | 8核16线程 | 建议分布式压测 |
| 高并发(> 10000 QPS) | 16核32线程及以上 | 必须分布式,注意网络瓶颈 |
2.1.2 内存:够用就好,但别省
内存这块,我的经验是:压测机内存 = 被测系统内存 × 1.5。为什么?因为压测工具本身要缓存响应数据、聚合结果,再加上操作系统开销,少了容易触发Swap。
- JMeter:每个线程约占用1~2MB堆内存,1000线程就是1~2GB,加上GUI本身,建议至少8GB。
- Locust:Python进程内存占用相对低,但协程模式下每个用户约几百KB,建议4GB起步。
- Gatling:基于Akka,内存管理比较高效,但建议也留6GB以上。
2.1.3 磁盘:IOPS才是关键
磁盘选型,很多人只看容量,其实压测场景下IOPS(每秒读写次数)才是关键指标。尤其是做日志记录、结果持久化时,磁盘IO很容易成为瓶颈。
| 磁盘类型 | 典型IOPS | 适用场景 |
|---|---|---|
| 机械硬盘(HDD) | 100~200 | 不推荐,除非只做极低并发 |
| SATA SSD | 5000~10000 | 中等规模压测,够用 |
| NVMe SSD | 50000~100000 | 高并发压测,首选 |
我个人习惯,压测机至少配一块NVMe SSD做系统盘和数据盘。如果条件有限,SATA SSD也能凑合,但千万别用HDD——你想想看,压测结果写到一半,磁盘队列深度飙到100+,那画面太美我不敢看。
2.1.4 网络:千兆是底线,万兆不嫌多
网络这块,我吃过不少亏。有一次压测一个API网关,本地压测机千兆网卡,被测服务器也是千兆,结果死活压不到目标QPS。后来一查,网卡跑满了,丢包率飙升。换了万兆网卡,问题直接解决。
选型建议:
- 千兆网卡:适合单机压测,QPS在5000以下。
- 万兆网卡:分布式压测或QPS超过5000时,必须上。
- 网线/交换机:别用劣质网线,至少超五类,最好六类。交换机端口不要共享带宽。
2.2 软件栈配置:OS、中间件与数据库
硬件选好了,软件配置也不能马虎。我见过太多人,硬件挺牛,结果操作系统参数没调,中间件配置没优化,压测一跑就崩。
2.2.1 操作系统调优
Linux是压测首选,Windows在并发场景下表现一般。我习惯用CentOS 7或Ubuntu 20.04 LTS,稳定且社区支持好。
关键参数调整:
# 文件描述符限制(默认1024,压测必须调大)
ulimit -n 65535
# 网络参数优化
sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.tcp_max_syn_backlog=65535
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_fin_timeout=30
# 内存参数
sysctl -w vm.swappiness=10
sysctl -w vm.dirty_ratio=30
sysctl -w vm.dirty_background_ratio=5
ulimit -n,结果JMeter跑到一半报Too many open files,整个压测白跑。现在我把这些参数写成了脚本,每次压测前自动执行。
2.2.2 中间件配置
中间件这块,我重点说Nginx和Tomcat,这两个是压测中最常见的。
| 中间件 | 关键参数 | 推荐值 | 说明 |
|---|---|---|---|
| Nginx | worker_processes | CPU核心数 | 充分利用多核 |
| Nginx | worker_connections | 65535 | 最大并发连接数 |
| Tomcat | maxThreads | 200~500 | 根据CPU和内存调整 |
| Tomcat | acceptCount | 100 | 等待队列长度 |
嗯,这里要注意:中间件的参数不是越大越好。比如Tomcat的maxThreads设成2000,CPU扛不住,反而会频繁上下文切换,吞吐量下降。我一般先设一个保守值,压测时观察CPU和线程数,再逐步调优。
2.2.3 数据库配置
数据库是压测中的重灾区。我见过最离谱的一次,压测时MySQL的max_connections没调,默认151,结果压到200并发直接报错。
MySQL关键参数:
# 连接数
max_connections = 500
# 缓冲池(设为物理内存的70%)
innodb_buffer_pool_size = 8G
# 日志文件大小
innodb_log_file_size = 1G
# 查询缓存(高并发下建议关闭)
query_cache_type = 0
query_cache_size = 0
2.3 压测工具选型:JMeter、Locust、Gatling
工具选型这事儿,没有绝对的好坏,只有合不合适。我三个工具都用过,说说我的感受。
2.3.1 JMeter:老牌劲旅,生态最全
JMeter是我用得最多的工具。优点很明显:
- 插件丰富:从HTTP到JDBC到MQ,几乎什么协议都能测。
- GUI友好:录制脚本、调试参数都很方便。
- 分布式支持:一台Master控制多台Slave,适合大规模压测。
缺点也有:
- 内存消耗大:GUI模式下尤其明显,我一般用命令行模式跑。
- 脚本维护麻烦:JMX文件是XML格式,版本控制不太友好。
2.3.2 Locust:Python党的最爱
Locust用Python写脚本,代码即配置。我比较喜欢它的协程模式,单机并发能力比JMeter强。
# 一个简单的Locust脚本
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
wait_time = between(1, 5)
@task
def index_page(self):
self.client.get("/")
@task(3)
def view_item(self):
self.client.get("/item?id=1")
优点:
- 代码可维护:Git管理方便,支持CI/CD集成。
- Web UI实时监控:跑的时候能看到实时QPS和响应时间。
缺点:
- 协议支持有限:主要支持HTTP,其他协议需要自己写。
- 分布式配置稍复杂:需要启动多个Worker进程。
2.3.3 Gatling:Scala加持,性能怪兽
Gatling基于Akka和Netty,性能是三个工具里最好的。我一般用它做高并发压测。
// 一个简单的Gatling脚本
class BasicSimulation extends Simulation {
val httpProtocol = http.baseUrl("http://localhost:8080")
val scn = scenario("BasicSimulation")
.exec(http("request_1").get("/"))
.pause(5)
setUp(
scn.inject(atOnceUsers(100))
).protocols(httpProtocol)
}
优点:
- 性能极高:单机可模拟数万并发。
- 报告精美:HTML报告自带图表,分析方便。
缺点:
- 学习曲线陡:需要懂Scala或Java。
- 调试不方便:编译型语言,改脚本要重新编译。
2.3.4 选型对比
| 维度 | JMeter | Locust | Gatling |
|---|---|---|---|
| 学习成本 | 低(GUI操作) | 中(Python基础) | 高(Scala/Java) |
| 单机并发能力 | 中(5000~10000) | 高(10000~30000) | 极高(30000+) |
| 协议支持 | 丰富(插件生态) | 有限(HTTP为主) | 中等(HTTP/WebSocket) |
| 报告质量 | 中(需插件增强) | 中(Web UI实时) | 高(HTML静态报告) |
| CI/CD集成 | 中(命令行模式) | 高(Python脚本) | 高(Maven/Gradle) |
我个人建议:团队有Python基础,选Locust;追求极致性能,选Gatling;通用场景,选JMeter。没有最好的工具,只有最适合你场景的工具。
2.4 环境搭建知识体系总览
说了这么多,我画了一张图,把环境搭建的核心逻辑串起来。你一看就明白:
这张图把环境搭建的三大模块和关键节点都串起来了。你搭建环境时,就按这个框架走:先搞定硬件,再调软件栈,最后选工具。每一步都有坑,但只要你按我说的来,至少能保证环境本身不出问题。