JMeter实战:模拟1000并发用户压测电商系统全流程指南
1. 项目概述与核心价值
最近在帮一个朋友的电商项目做性能摸底,他们刚做完一波大促活动复盘,发现高峰期订单处理延迟明显,客服那边也收到了不少关于页面加载慢的抱怨。老板拍板说,下次大促前必须把系统的“抗压能力”搞清楚。于是,这个任务就落到了我头上。性能测试工具很多,但综合考虑团队技术栈、学习成本和社区生态,我最终还是选择了老牌且开源的Apache JMeter。这次的目标很明确:模拟1000个并发用户在典型电商场景下的操作,看看网站到底能扛到什么程度,瓶颈在哪里。
为什么是1000个并发?这不是一个随便拍脑袋的数字。对于大多数处于成长期的中小型电商网站来说,1000个并发用户是一个比较有代表性的压力阈值。它意味着在促销秒杀、热点商品发布等场景下,可能同时有上千人在浏览商品、加购物车、提交订单。这个量级足以暴露大部分数据库连接池、应用服务器线程池、缓存以及网络带宽的配置问题,但又不会因为压力过大而直接“压垮”测试环境,导致无法有效分析。通过这次实战,你不仅能学会配置一个完整的JMeter测试计划,更能理解性能测试背后的设计思路和问题分析方法,这对于后端开发、运维乃至产品经理理解系统边界都至关重要。
2. 测试环境与核心工具准备
工欲善其事,必先利其器。在开始编写复杂的测试脚本之前,一个稳定、干净的测试环境是基础。这里的环境包括两部分:一是施压机(运行JMeter的机器),二是被测系统(你的电商网站)。
2.1 JMeter与JDK安装避坑指南
首先,JMeter是纯Java应用,所以必须先安装Java Development Kit (JDK)。我强烈推荐使用JDK 8或JDK 11的LTS(长期支持)版本,这两个版本与JMeter的兼容性经过了最广泛的验证。直接从Oracle官网或AdoptOpenJDK这类开源站点下载安装包即可。安装后,务必配置好JAVA_HOME环境变量,并将%JAVA_HOME%\bin添加到系统的PATH中。在命令行输入java -version能正确显示版本信息,这一步才算成功。
接下来是JMeter本身。去Apache JMeter官网下载最新的二进制压缩包(例如apache-jmeter-5.6.3.zip),解压到任意目录,比如D:\Tools\apache-jmeter-5.6.3。它的目录结构很清晰:bin/下是启动脚本,lib/下是所有依赖的jar包。为了后续操作方便,我同样建议将JMeter的bin目录路径(如D:\Tools\apache-jmeter-5.6.3\bin)添加到系统的PATH环境变量中。这样,你就可以在任意命令行窗口直接输入jmeter来启动图形界面,或者jmeter -n -t testplan.jmx -l result.jtl来以非GUI模式执行测试了。
注意:很多新手会遇到启动JMeter后界面乱码,或者运行时报内存不足(
java.lang.OutOfMemoryError)的问题。乱码通常是因为Windows命令行或JMeter配置文件编码问题,可以修改bin/jmeter.properties文件中的sampleresult.default.encoding=UTF-8。内存不足则需要修改bin/jmeter.bat(Windows)或bin/jmeter(Linux/Mac)启动脚本,找到HEAP相关设置,例如将set HEAP=-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m调整为-Xms2g -Xmx4g,根据你施压机的物理内存来定,一般给4G堆内存足够应对1000并发的脚本运行。
2.2 被测电商网站环境确认
性能测试必须在独立于生产环境的测试环境进行,这是铁律。你需要一个尽可能贴近生产环境配置的测试环境:相同的服务器规格(CPU、内存)、相同的中间件版本(如Nginx、Tomcat、Redis、MySQL)、相同的应用代码版本和配置。如果测试环境和生产环境差异巨大,那么测试结果将毫无参考价值。
在开始前,你需要从开发和运维团队获取以下关键信息:
- 应用访问入口:测试环境的域名或IP地址和端口。
- 核心业务接口:用户登录、商品列表查询、商品详情页、加入购物车、提交订单、支付回调等主要API的URL和请求方式(GET/POST)。
- 测试账号与数据:准备一批测试用户账号(至少1000个,用于模拟不同用户登录),以及足够丰富的测试商品数据。数据量级(如商品表记录数)也应尽量模拟生产。
- 监控权限:确保你拥有权限查看或访问测试服务器的系统监控(如CPU、内存、磁盘IO)、应用监控(如JVM GC日志、线程池状态)和数据库监控(如慢查询日志、连接数)。这些是定位瓶颈的“眼睛”。
3. 测试计划设计与核心逻辑拆解
打开JMeter,第一个看到的就是“测试计划”。你可以把它理解为一个项目的总容器。右键点击“测试计划”,选择“添加” -> “线程(用户)”,我们先来创建模拟用户的核心组织单元——线程组。
3.1 线程组配置:模拟1000个真实用户的行为
线程组是JMeter中所有测试逻辑的起点,它定义了虚拟用户的数量、启动方式、执行次数等核心参数。
- 创建线程组:右键“测试计划” -> “添加” -> “线程(用户)” -> “线程组”。
- 关键参数配置:
- 线程数(用户):这里填入我们的目标1000。这代表JMeter会创建1000个独立的线程来模拟1000个并发用户。
- Ramp-Up时间(秒):这是非常重要的一个参数。它表示JMeter用多长时间来启动全部线程。如果设置为0,JMeter会立即创建1000个线程并同时发起请求,这对系统是一个巨大的瞬时冲击,往往不真实。更真实的场景是用户逐渐涌入。假设我们希望1000个用户在1分钟内陆续上线,那么这里就填60。JMeter会计算出一个启动速率(1000线程 / 60秒 ≈ 16.7线程/秒),即每秒启动约17个新用户。
- 循环次数:每个线程(用户)执行测试脚本的次数。如果勾选“永远”,线程会一直执行直到手动停止。对于本次定压测试,我们更关心系统在持续压力下的表现。我建议先设置为一个较大的固定数,比如100,或者直接勾选“永远”,然后通过调度器来控制总时长。
- 调度器:勾选线程组下方的“调度器”复选框。这里可以设置测试的精确持续时间。例如,在“持续时间(秒)”中填入600,意味着无论循环次数设了多少,整个测试只运行10分钟。这比单纯设置循环次数更好控制测试时长。
实操心得:
Ramp-Up时间需要根据业务场景谨慎设置。对于“秒杀”场景,这个时间可能很短(如10秒);对于日常高峰,可能是几分钟到几十分钟。设置不当可能导致压力曲线不符合预期,要么瞬间压垮系统,要么压力迟迟上不去。
3.2 构建核心业务场景:HTTP请求与参数化
线程组定义好了“用户军团”,接下来要定义每个“士兵”做什么。电商的核心场景通常是一条链路:首页浏览 -> 搜索/查看商品 -> 登录 -> 加入购物车 -> 下单 -> 支付(或模拟)。我们需要用JMeter的采样器来模拟这些HTTP请求。
添加HTTP请求默认值:为了避免在每个HTTP请求采样器中重复填写协议、服务器地址、端口,我们可以先添加一个配置元件。右键线程组 -> “添加” -> “配置元件” -> “HTTP请求默认值”。在这里填入测试环境的协议(http/https)、服务器名称或IP、端口号。这样,后面添加的具体HTTP请求只需要填写路径即可。
添加事务控制器(可选但推荐):为了将一系列操作(如“登录流程”)组合在一起,并获取该流程的整体响应时间,可以添加事务控制器。右键线程组 -> “添加” -> “逻辑控制器” -> “事务控制器”。给它起个名字,比如“用户登录”。之后,把登录相关的请求都拖到这个控制器下面。
创建第一个请求:访问首页:
- 右键“事务控制器”或“线程组” -> “添加” -> “采样器” -> “HTTP请求”。
- 名称:
01_访问首页。 - 因为配置了“HTTP请求默认值”,这里只需在“路径”栏填写首页的路径,如
/或/index.html。 - 方法通常是
GET。
关键步骤:用户登录与参数化: 登录操作通常是
POST请求,需要提交用户名和密码。我们不可能让1000个用户都用同一个账号登录,这不符合真实场景,也容易触发系统的防刷机制。因此,必须进行参数化。- 准备CSV数据文件:创建一个
users.csv文件,内容如下:username,password user001,pass001 user002,pass002 ... (至少1000行) user1000,pass1000 - 添加CSV数据文件设置:右键线程组 -> “添加” -> “配置元件” -> “CSV数据文件设置”。
- 文件名:浏览选择你的
users.csv文件完整路径。 - 文件编码:
UTF-8。 - 变量名称:
username,password(与CSV文件表头对应)。 - 其他选项:
遇到文件结束符再次循环?选True(如果线程数多于数据行数,则从头开始复用);遇到文件结束符停止线程?选False。
- 文件名:浏览选择你的
- 创建登录请求:
- 添加一个新的HTTP请求,命名为
02_用户登录。 - 方法:
POST。 - 路径:填写登录接口路径,如
/api/user/login。 - 转到“Body Data”选项卡(如果接口接收JSON)或“Parameters”选项卡(如果接收表单)。
- 以JSON为例,在Body Data中写入:
{"username":"${username}","password":"${password}"}。这里的${username}和${password}就是引用CSV文件中的变量。
- 添加一个新的HTTP请求,命名为
- 处理登录后的Token/Session:登录成功后,服务器通常会返回一个Token或设置一个Session Cookie,后续请求需要携带它来保持登录状态。
- 在登录请求下,添加一个正则表达式提取器(或更强大的JSON提取器):右键登录请求 -> “添加” -> “后置处理器” -> “JSON提取器”。
- 名称:
提取登录Token。 - JSON路径表达式:假设返回的JSON是
{"code":0, "data":{"token":"eyJhbGciOiJ..."}},那么表达式可以写$.data.token。 - 变量名称:
auth_token。 - 后续的请求(如加购、下单),需要在HTTP请求的“Header管理器”中添加一个Header:
Authorization: Bearer ${auth_token}。
- 准备CSV数据文件:创建一个
继续构建后续请求:用同样的方法,添加“03_浏览商品列表”、“04_查看商品详情”、“05_加入购物车”、“06_提交订单”等HTTP请求。注意,加入购物车和提交订单通常是
POST请求,且需要携带商品ID、数量等参数,这些参数同样可以从预先准备好的CSV文件中读取,或者使用JMeter函数(如__Random)动态生成。
3.3 让测试更真实:定时器与断言
真实的用户操作之间是有间隔的,不会毫秒不停地点击。为了模拟这种“思考时间”,我们需要添加定时器。
- 高斯随机定时器:这个定时器模拟的是大部分用户集中在某个平均思考时间附近的行为,比较符合现实。右键某个请求或事务控制器 -> “添加” -> “定时器” -> “高斯随机定时器”。可以设置“偏差”为200毫秒,“常数延迟偏移”为500毫秒,这意味着延迟时间会在 (500-200)ms 到 (500+200)ms 之间随机分布,即300ms到700ms。
另外,我们需要验证服务器返回的结果是否正确,而不仅仅是看它是否响应。这就需要断言。
- 响应断言:右键某个请求 -> “添加” -> “断言” -> “响应断言”。例如,对于登录请求,我们可以断言响应文本中包含
"code":0,或者响应代码等于200。如果断言失败,JMeter会将该次采样标记为失败,在结果分析时就能清晰看到。
3.4 收集测试结果:监听器配置
测试跑起来,我们需要工具来收集和查看结果。JMeter提供了多种监听器。注意,监听器本身会消耗不少内存和CPU,在正式压测时(非GUI模式),我们通常只使用最基础的监听器将结果写入文件,事后再用GUI模式加载分析。
- 聚合报告:右键线程组 -> “添加” -> “监听器” -> “聚合报告”。这是一个核心的监听器,运行测试后,它会显示所有请求样本的聚合数据,包括:样本数、平均值、中位数、90%百分位、95%百分位、最小值、最大值、异常率、吞吐量(Requests/sec)等。90%/95%百分位响应时间是评估系统性能的关键指标,它表示有90%/95%的请求响应时间低于这个值,比平均响应时间更能反映用户体验。
- 查看结果树:主要用于调试脚本。它会详细展示每一个请求和响应的内容,在正式压测时务必禁用或删除,因为它会记录所有细节,产生巨大的内存开销,导致施压机自己先OOM(内存溢出)。
- 用表格查看结果:以表格形式展示每个样本的结果,也适用于小规模调试。
- 后端监听器:这是进行长时间压测的推荐方式。它可以异步地将采样结果写入到文件(如CSV)或发送到时序数据库(如InfluxDB),然后配合Grafana进行实时可视化展示,对施压机性能影响最小。添加“后端监听器”,配置输出格式为CSV,并指定一个结果文件路径,如
result_${__time(yyyyMMdd-HHmmss)}.jtl。
4. 分布式压测与资源监控
当你用单台机器模拟1000个并发用户时,可能会遇到瓶颈:不是被测系统撑不住,而是你的施压机(JMeter所在机器)网络带宽、CPU或内存先达到极限,无法产生足够的压力。这时,就需要使用JMeter的分布式压测功能。
4.1 分布式压测原理与配置
分布式压测的原理是:一台机器作为控制机,只负责管理和分发测试脚本,不产生压力;多台其他机器作为施压机,接收控制机指令,实际执行测试脚本并向被测系统发送请求。所有施压机的测试结果会回传至控制机进行汇总。
配置步骤:
- 准备施压机:确保所有施压机和控制机安装了相同版本的JMeter和JDK。最好也保持相同的插件等。
- 修改施压机JMeter配置:在所有施压机上,编辑
bin/jmeter.properties文件,找到server.rmi.ssl.disable这一项,将其值改为true(关闭SSL,简化配置)。同时,找到server_port(默认1099)确认端口可用。 - 启动施压机Agent:在每台施压机上,运行
bin/jmeter-server.bat(Windows)或bin/jmeter-server(Linux/Mac)。看到类似Started remote object的日志,表示启动成功。 - 配置控制机:在控制机上,编辑
bin/jmeter.properties文件,找到remote_hosts配置项,将施压机的IP地址和端口(默认1099)添加进去,例如:remote_hosts=192.168.1.101:1099,192.168.1.102:1099。 - 远程启动测试:在控制机的JMeter GUI中,打开你的测试计划,点击菜单栏“运行” -> “远程启动”,选择其中一台施压机,或者直接“远程启动所有”,测试就会在所有施压机上同步执行。
注意事项:分布式压测时,要确保所有施压机上的CSV数据文件路径一致,或者使用共享存储。更稳妥的做法是,在测试计划中使用
__StringFromFile或__CSVRead函数来读取位于控制机共享目录下的数据文件(需确保网络可达)。同时,要监控施压机本身的资源使用情况,避免其成为瓶颈。
4.2 全方位监控被测系统
性能测试不只是看JMeter的报告,更重要的是结合被测系统的资源监控数据,进行关联分析。你需要监控以下几个层面:
系统层监控:
- CPU使用率:使用
top(Linux) 或Performance Monitor(Windows) 查看。重点看%us(用户态)和%sy(内核态)。如果%us持续高于70%,可能应用代码有计算瓶颈;如果%sy很高,可能是系统调用频繁或上下文切换过多。 - 内存使用:关注已用内存、缓存/缓冲内存以及Swap使用情况。如果Swap被频繁使用,说明物理内存不足,性能会急剧下降。
- 磁盘I/O:使用
iostat或vmstat查看磁盘的读写等待时间(await)和利用率(%util)。如果%util持续接近100%,说明磁盘I/O是瓶颈。 - 网络I/O:使用
iftop,nethogs或sar -n DEV查看网络带宽是否被打满,以及是否有大量的TCP重传或错误。
- CPU使用率:使用
应用层监控:
- Web服务器(如Nginx):监控活跃连接数、请求处理速率(Requests per second)、上游(如Tomcat)响应时间。
- 应用服务器(如Tomcat/JVM):
- JVM GC:通过
jstat或GC日志分析Full GC的频率和耗时。频繁的Full GC会导致应用暂停(Stop-The-World),是响应时间毛刺的常见原因。 - 线程池:查看应用服务器(如Tomcat)的HTTP线程池使用情况。如果活跃线程数持续达到最大值,且队列堆积,说明线程池配置不足或下游(如数据库)响应慢。
- JVM GC:通过
- 数据库(如MySQL):
- 慢查询日志:这是定位SQL性能问题的金钥匙。压测期间一定要开启并分析慢查询日志。
- 连接数:监控
Threads_connected和Threads_running。如果连接数接近max_connections上限,或者大量连接处于Sleep状态,需要优化连接池配置或SQL。 - InnoDB状态:关注
Innodb_row_lock_waits(行锁等待)、Innodb_buffer_pool_hit_rate(缓冲池命中率,应高于99%)。
使用专业监控工具:对于复杂的系统,建议使用APM(应用性能管理)工具,如SkyWalking,Pinpoint,Arthas等。它们可以自动追踪请求在分布式系统中的完整调用链路,精确到每个方法、每个SQL的耗时,是定位性能瓶颈的利器。
5. 执行测试与结果深度分析
一切准备就绪后,就可以开始执行测试了。强烈建议先在GUI模式下用少量线程(如10个)跑一遍,确保脚本逻辑正确,参数化、关联、断言都正常工作。调试无误后,再使用非GUI模式进行正式压测。
5.1 非GUI模式执行与结果收集
在控制机的命令行中,切换到JMeter的bin目录,执行以下命令:
jmeter -n -t D:\path\to\your\testplan.jmx -l D:\path\to\result\result_20241027.jtl -e -o D:\path\to\html\report-n: 非GUI模式。-t: 指定测试计划文件(.jmx)。-l: 指定结果文件(.jtl或.csv)。-e: 测试结束后生成HTML报告。-o: 指定生成HTML报告的目录(必须为空目录或不存在)。
这个命令会启动测试,并将原始的采样结果写入.jtl文件,测试结束后会自动生成一个美观的HTML仪表盘报告。
5.2 核心性能指标解读
测试完成后,打开聚合报告或HTML报告,你需要重点关注以下指标:
- 吞吐量:单位时间内系统处理的请求数(Requests/sec)。这是衡量系统处理能力的核心指标。在并发用户数增加时,吞吐量会先上升,达到一个峰值后可能持平或下降。峰值吞吐量就是系统在当前场景下的最大处理能力。
- 响应时间:
- 平均响应时间:参考价值一般,容易受极端值影响。
- 90%/95%/99%百分位响应时间(P90, P95, P99):这是黄金指标。例如P95=800ms,意味着95%的用户请求响应时间在800ms以内。这个指标直接关系到用户体验。通常,P95响应时间应在1-2秒以内为佳。
- 错误率:失败的请求数占总请求数的百分比。在性能测试中,错误率应控制在极低水平(如<0.1%)。如果错误率随压力上升而飙升,说明系统存在功能或稳定性问题。
- 并发用户数:即我们设置的线程数。观察在不同并发数下,上述指标的变化趋势,可以绘制出系统的性能曲线。
5.3 性能瓶颈分析与调优思路
结合JMeter结果和系统监控数据,进行瓶颈分析:
场景一:响应时间随并发线性增长,吞吐量上不去,CPU/内存使用率低。
- 可能原因:外部依赖(如数据库、第三方接口)响应慢;应用内部有同步锁或串行化瓶颈;线程池配置过小,请求在队列中等待。
- 排查方向:查看数据库慢查询;使用APM工具分析调用链耗时;检查应用日志是否有等待或超时;调整应用服务器和数据库连接池大小。
场景二:吞吐量达到一个峰值后不再上升,甚至下降,错误率(特别是超时错误)升高,服务器CPU使用率接近100%。
- 可能原因:应用服务器或数据库服务器资源耗尽(CPU算力、内存、线程)。
- 排查方向:检查是否有代码层面的性能问题(如低效算法、循环查询DB);分析JVM GC日志,看是否因频繁Full GC导致;检查数据库的CPU和锁情况;考虑垂直升级(提升单机配置)或水平扩展(增加服务器节点)。
场景三:网络带宽或磁盘IO成为瓶颈。
- 可能原因:大量静态资源(图片、JS、CSS)请求,或报告、导出等大数据量操作。
- 排查方向:使用CDN分发静态资源;对大数据量操作进行分页或异步导出;优化数据库查询,减少不必要的数据传输。
6. 常见问题与实战避坑指南
在实际操作中,你肯定会遇到各种各样的问题。这里记录了几个我踩过的坑和对应的解决方案。
6.1 JMeter自身问题
“java.net.BindException: Address already in use” 或 “无法创建大量TCP连接”
- 问题:在Windows上,当JMeter作为施压机需要创建大量TCP连接时,可能会耗尽本地临时端口(范围通常是1024-5000)。
- 解决:
- 调整操作系统参数:对于Windows,可以修改注册表
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters,添加DWORD值MaxUserPort,设置为十进制 65534;添加TcpTimedWaitDelay,设置为十进制 30。修改后重启生效。 - 优化JMeter配置:在
bin/jmeter.properties中,设置httpclient4.time_to_live为一个较低的值(如5000),让连接更快关闭复用。使用HTTP连接池(HTTP Request Defaults 或 单个请求中勾选“Use KeepAlive”)。 - 使用分布式压测:将压力分散到多台施压机,从根本上减少单机连接数。
- 调整操作系统参数:对于Windows,可以修改注册表
“Out of Memory” 内存溢出错误
- 问题:测试计划太复杂,监听器(尤其是“查看结果树”)未禁用,或堆内存设置太小。
- 解决:
- 正式压测时,务必禁用或删除“查看结果树”、“用表格查看结果”等消耗内存的监听器。
- 使用“后端监听器”将结果直接写入文件。
- 增大JMeter启动内存,修改
bin/jmeter.bat中的HEAP参数,例如set HEAP=-Xms4g -Xmx8g(根据机器内存调整)。 - 尝试以非GUI模式运行。
“SSL握手”相关问题
- 问题:测试HTTPS接口时出现SSL错误。
- 解决:在“HTTP请求”的“高级”选项卡中,尝试选择不同的“实现”(如
HttpClient4)。如果测试环境使用自签名证书,需要在JMeter中安装该证书,或者直接勾选“忽略SSL证书错误”的选项(仅限测试环境!)。
6.2 脚本与场景设计问题
参数化数据重复导致业务冲突
- 问题:使用CSV文件参数化用户和商品,但多个虚拟用户可能操作同一件商品库存,导致超卖或业务逻辑错误。
- 解决:设计测试数据时,确保关键业务数据(如商品库存)足够多,或者使用JMeter函数(如
__Random,__RandomString)动态生成唯一标识符。对于库存扣减,可以准备一批“测试专用商品”,库存量设置得足够大。
未能正确模拟浏览器行为
- 问题:JMeter默认不执行JavaScript,也不处理页面内的重定向和资源加载(如图片、CSS、JS)。
- 解决:对于需要测试前端页面加载性能的场景,应使用WebDriver Sampler插件,直接驱动真实浏览器(如Chrome)进行测试。对于API压测,则无需关心这些。如果后端接口依赖前端生成的Token(如CSRF Token),可能需要先通过一个请求获取Token,再用正则表达式提取器获取并传递给下一个请求。
断言过于严格导致大量误报失败
- 问题:断言响应中必须包含某个固定字符串,但服务器返回的提示信息可能因情况略有不同。
- 解决:使用更灵活的断言方式,如“响应代码”断言(只检查是否为200),或使用“正则表达式”断言来匹配一个模式而非固定字符串。对于JSON响应,使用“JSON断言”更精准。
6.3 测试结果分析误区
只关注平均值
- 误区:平均响应时间看起来不错,就认为系统性能达标。
- 纠正:必须关注P90/P95/P99响应时间。少数慢请求会严重影响这部分用户的体验,而平均值会掩盖这个问题。一个P99很高的系统,意味着每100个请求就有1个很慢,在千万级流量下就是十万级的用户投诉。
测试时间过短
- 误区:只运行1-2分钟,看到指标正常就下结论。
- 纠正:性能测试需要一定时长(如10-30分钟以上),以观察系统在持续压力下的表现。短时间测试可能无法触发内存泄漏、连接池耗尽、缓存穿透等问题。稳定性测试(耐力测试)通常需要持续运行数小时甚至更久。
忽略环境差异
- 误区:在配置远低于生产环境的测试机上测试,结果良好。
- 纠正:性能测试环境的硬件、软件、数据、网络配置必须尽可能与生产环境对齐。否则,测试结果无法用于生产容量评估。这就是所谓的“性能测试环境独立性”原则。
完成一轮完整的性能测试,输出一份清晰的报告,指出系统的当前性能基线、瓶颈点以及优化建议,你的工作就非常有价值了。性能测试不是一个一次性的任务,而是一个“测试->分析->调优->再测试”的循环过程。通过这次用JMeter模拟1000并发用户测试电商网站的实战,你掌握的不只是一个工具的使用,更是一套定位和解决性能问题的系统工程方法。下次当老板再问“咱们的系统能扛住多少人”时,你就可以拿出数据,自信地给出答案了。
