恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
JMeter并发数设置全解析:线程组、TPS与阶梯加压实战
首页
资讯中心
/
JMeter并发数设置全解析:线程组、TPS与阶梯加压实战
JMeter并发数设置全解析:线程组、TPS与阶梯加压实战
发布时间:2026/10/4 16:39:29
1. 并发数的本质先搞清楚你到底在压什么1.1 为什么我说“并发数”这个词被用烂了做性能测试的朋友第一次上手 JMeter往往第一句就会问“并发数在哪设置”然后打开线程组把“线程数”填成 1000以为这就是 1000 并发。一年前我也是这么干的直到被组长指着聚合报告里的 TPS 数字问了一句“你的并发呢”我才发现自己根本没答上来。先说结论JMeter 里的线程数只是并发用户的模拟载体它不等于真实的并发请求数。并发数以“线程数”的形式配置但实际打到服务端的“并发压力”是由线程数、循环次数、Think Time、Ramp-Up、以及每个线程内 Sampler 的数量共同决定的。稍不注意你设置了 1000 线程实际同一时刻可能只有 200 个请求在线上剩下 800 个线程都处于等待响应的状态。所以本文不打算只告诉你“线程数填多少”这种浅层答案。我会把并发数的计算逻辑、常见负载模型、阶梯加压方法、以及 JMeter 自身限制全部拆开来讲。你可以把它当成一篇从“会填参数”到“会设计压测场景”的过渡文章。1.2 线程数、用户数、并发请求数三者不是一回事很多刚接触性能测试的人会把下面三个概念混在一起其实它们差异非常大用户数指系统需要承载的总注册用户或活跃用户规模比如 10 万注册用户。这个数字主要用于估算不直接等于压测负载。线程数JMeter 中每个线程模拟一个虚拟用户。你设置 100 个线程就是同时有 100 个虚拟用户在执行脚本动作。并发请求数某个瞬间真正到达服务端的请求数量。这个数字取决于线程数和请求耗时。通俗地解释你去银行办业务大厅有 100 个座位线程数但真正同时趴在窗口办业务的人并发请求数不会超过柜台数量。如果每笔业务需要 3 分钟那么座位再多同一时刻办理中的业务也就是柜台数的量级。假设银行有 10 个窗口哪怕 100 个人在大厅坐着排队客户眼中的“并发”最多也只有 10 笔在进行中。这时候你说“我有 100 并发”客户肯定不会认。放在 JMeter 里也一样线程组设置了 100 线程线程 1 发起请求后等待响应如果响应时间为 500ms而脚本里每个线程做完一次请求马上进入下一轮那这 100 个线程可能在任意时刻都有 100 个请求在途。但如果每个线程内部加了 2 秒的固定定时器那么同一时刻平均在途的请求数就低于 100真实并发会大幅缩水。1.3 吞吐量与 RPS衡量并发效果的核心指标要判断并发设置到底有没有生效最终看的是RPSRequests Per Second每秒请求数或TPSTransactions Per Second每秒事务数。并发数只是手段吞吐量才是可观测的结果。吞吐量和并发数之间存在这样一个关系RPS ≈ 并发线程数 / 平均响应时间举个例子设置 500 个线程每个请求平均响应时间是 0.5 秒那么理论吞吐量 ≈ 500 / 0.5 1000 RPS。如果把响应时间压到 0.25 秒其它不变吞吐量就会跑到约 2000 RPS。反过来如果你发现线程数已经加到 2000 了RPS 却一直稳定在 3000 左右不动那基本可以判断瓶颈不在线程数上而是被测服务或压测机自身到了上限。这也就是为什么很多资深测试员做压测时并不盲目追求“线程数越大越威风”。他们更关心负载模型下的RPS 曲线是否和目标一致。本文后续会给出两种实现路径一种是直接设线程数另一种是按目标 RPS 来反推并发量。2. 线程组的参数明细手把手把并发数配置到位2.1 线程组里的几个核心字段到底怎么填打开 JMeter 的线程组你会看到线程数、Ramp-Up 时间和循环次数三个最基本的设置。很多教程只会让你填数但不会告诉你这三个数字的内在逻辑。线程数对应的是虚拟用户的规模。具体填多少取决于你的测试目标。如果是做容量测试通常把线程数设成预期峰值的 1.5 到 2 倍留出余量如果是做稳定性测试线程数则设置到恰好支撑目标 RPS 的水平然后持续跑数小时。Ramp-Up 时间是 JMeter 在多少秒内启动完全部线程。默认是 0表示立即同时启动所有线程。在演示、压测集群时Ramp-Up 设成 0 做突袭式压测是有意义的能测出服务在瞬间高并发下的表现。但如果模拟真实用户逐步进场最好把 Ramp-Up 时间设成一个非零值比如每 5 秒增加 50 个线程。循环次数决定了每个线程执行多少次请求。如果只做一次冒烟测试填 1 即可做持续压测可以直接勾选“永远”再配合持续时间来控制。我个人的经验循环次数不推荐填一个很大的固定值比如 999999因为这样压测时长完全不可控。更规范的做法是把“循环次数”设为永远然后用“持续时间”来控制压测结束时间这样配合命令行跑自动化更舒服。2.2 调度器Scheduler的用法与典型场景线程组面板最下方的“调度器配置”很多人以为只是设置总运行时长实际上它包含两个关键字段持续时间和启动延迟。持续时间从测试开始到测试结束的总时长单位秒。配合“循环次数永远”使用可以在固定时间内完成压测。启动延迟JMeter 等待多少秒后开始发起请求适合等待服务就绪的情况。典型的用法是做一个 15 分钟的稳定性测试线程数设为 500Ramp-Up 设为 120 秒循环次数永远持续时间 900 秒。这样 JMeter 在 120 秒内把 500 个线程逐步拉满然后在满并发下继续跑 13 分钟总共历时 15 分钟。这个模型比“一开跑就 500 个线程同时打”更贴近真实系统的用户增长曲线也更容易观察服务在扩容过程中的表现。2.3 循环次数、Think Time 和请求耗时的组合策略同样一个“500 线程”的配置由于循环次数和定时器不同产生的压力完全不一样。设 500 个线程循环 1 次一共只有 500 个请求设 500 个线程循环永远 持续 5 分钟那请求数就看每个线程的并发执行速度可能数千甚至数万。这里面还有个很容易被忽略的点——请求耗时。如果被测接口非常快比如 3ms 返回那 500 个线程跑出来非常高的 RPS服务端可能先被压爆。如果接口很慢比如 3 秒才返回那 500 个线程同一时刻在途请求也可能达到 500压力并不小。进阶玩法是在线程组下面加一个“固定定时器Constant Timer”模拟真实用户阅读页面、填表单的思考时间。吞吐量会明显下降但这更接近真实行为。做压力测试和容量测试时建议不加或加很小的 Think Time充分探底做真实用户模拟时Think Time 是必备元素。3. 阶梯加压让并发数从“一刀切”变成“渐增曲线”3.1 为什么要阶梯加压直接上 1000 个线程做压测得到的结果往往是一堆错误和超时但你分不清服务是从哪个并发段开始崩的。阶梯加压的核心目的就是让并发数按既定节奏逐级增加找到系统的拐点。拐点是指服务端开始出现明显性能恶化的并发边界。比如并发 200 时响应时间 50ms并发 400 时 80ms并发 600 时突然涨到 600ms 且错误率抬升那这就是容量规划里的关键数据。没有阶梯加压你就拿不到这种曲线。用现实生活中的例子理解考一个人的负重能力你不会直接往他肩上压 100 公斤那样只会出现两个结果——要么咬牙扛住了要么直接受伤但你不知道他 60 公斤和 80 公斤时的状态差异。分级加量才能测出真实阈值。3.2 用 Stepping Thread Group 插件实现阶梯负载JMeter 原生线程组不支持按时间段自动增加线程数但可以通过 JMeter Plugins 扩展实现。最常用的是jpgc - Stepping Thread Group在插件管理器里搜索安装即可使用。Stepping Thread Group 的关键设置如下Start Threads Count起始线程数。First Wait For测试开始后等待多久才开始加压。Then Start Threads Count每级增加多少线程。Then Wait For每级加压后保持多久。Threads Increment Per Step每级增加的线程数。Ramp-Up Time Per Step每级增加线程所花的时间。Hold Load For全部线程启动后保持负载多长时间。举个例子把 Start Threads Count 设为 50每级增加 50每级保持 60 秒总线程数到达 500 后保持 10 分钟。这样你会得到一条非常平滑的阶梯曲线可以在聚合报告或监听器里清楚看到每个并发阶段的响应时间波动。3.3 Concurrency Thread Group 吞吐量定时器的组合用法另一个更专业的组合是Concurrency Thread Group配合Throughput Shaping Timer。Concurrency Thread Group 可以设置目标并发数并通过定时器来控制 RPS 变化。这套组合的最大价值是并发数和吞吐量之间的映射关系不再靠手动算而是由定时器直接控制。你可以设定“前 60 秒每秒 100 次接下来 120 秒每秒 300 次……”这种更精细的 RPS 曲线常用在容量规划场景。安装Throughput Shaping Timer后在定时器配置里添加一个时间段列表每一行代表一个时间区间内的目标 TPS。JMeter 会自动调整请求发起频率来贴合这些目标值。跑完之后监听器里能直接对比目标曲线和实际曲线非常直观。3.4 原生功能做渐变Threads 逐步增加的替代方案如果你不方便装插件JMeter 原生也能模拟简单阶梯。实现思路是用多个线程组每个线程组设置不同的线程数和启动延迟再通过“SetUp Thread Group”或者使用“命令行参数动态指定负载”的方式分别执行。比如建 4 个线程组第一个线程组 100 线程启动延迟 0 秒跑 1 分钟第二个线程组 200 线程启动延迟 60 秒跑 1 分钟第三个线程组 300 线程启动延迟 120 秒跑 1 分钟。测试计划整体总时长 3 分钟就能得到一个粗糙的阶梯效果。用这种方法的人较少因为管理和维护都不方便且多线程组之间资源竞争难以精确控制。如果你要上线生产级压测任务还是推荐插件方案。4. 目标并发压测的真实目标其实是这样算出来的4.1 先把目标并发算出来很多人设并发数凭感觉先跑 200不行跑 500再不行跑 1000。但专业的性能测试在写脚本之前就应该先定好目标。目标并发量的计算依赖 RA 数据业务预估和接口容量。最简化的公式有两类按在线用户数估算目标并发 在线用户数 × 同时操作比例比如某产品峰值在线用户 2 万人同时操作比例按 5% 估算那目标并发 1000。按目标 TPS 反推目标并发 目标 TPS × 平均响应时间比如你想让系统支撑 5000 TPS而接口平均响应时间是 100ms那么并发 5000 × 0.1 500。这个数值可以作为初始线程数的参考。这里要强调“初始”两个字。实际压测中线程数和 TPS 不是完全线性的关系因为线程多了以后CPU 调度、网络连接复用、服务端线程池饱和都会让吞吐量上升变慢最终进入平缓期。这个平缓期对应的并发数就是系统的有效容量上限。4.2 用 Throughput Shaping Timer 设定精确 TPS如果你已经明确目标 TPS 而不是目标线程数强烈建议直接用 Throughput Shaping Timer。它的逻辑很简单无论你后台线程组设成多少线程它都会通过动态调节请求发起速率把实际 TPS 控制在目标范围内。这种工作方式的好处是你不用担心“线程数设少了导致 TPS 不够”只要线程序数留够余量定时器会自行调整实际发压速率。用大白话说线程数是“可用的手”定时器是“节流阀”。配置示例阶段 10-300 秒目标 TPS 200阶段 2300-600 秒目标 TPS 500阶段 3600-900 秒目标 TPS 1000跑出来的结果直接和业务容量目标对照省去了很多人为调参的过程。4.3 通过 CSV 和参数化实现数据驱动并发并发数设置还有一个容易被忽略的维度业务数据隔离。真实场景中并发用户不会都用同一个账号、同一个商品 ID。如果所有线程打同一个接口、传同样的参数JMeter 会命中服务端缓存测出来的结果虚高。我的建议是为并发测试准备一组参数化数据存成 CSV通过 CSV Data Set Config 分发给每个线程。例如 5000 个用户账号、5000 个商品 ID在 1000 并发下每个线程取一条保证请求的数据不重叠。具体做法CSV 配置中设置“共享模式”为All threads每次迭代自动读取下一行。如果需要每个线程独立的数据段可以改用Current thread模式CSV 行数只要大于线程数即可。4.4 真实“并发用户”场景模型示例最后补充一个偏业务的建模思路。假设我们测一个电商秒杀接口业务要求 1 分钟内承受 10 万次下游调用每次调用平均耗时 200ms。那么目标 TPS 100000 / 60 ≈ 1667。平均并发 1667 × 0.2 ≈ 334。为了使压测充分且通过波动验证容量线程数建议设置为平均并发的 2 倍左右即 600-700并设置合理的 Ramp-Up 时间。这里体现的思路是并发数设置不是拍脑袋而是业务目标、接口平均耗时和资源冗余三个因素共同推导的结果。5. 限制你并发数上不去的很可能不是被测系统5.1 谁能拦住并发数的一堵隐墙压测过程中最尴尬的事情不是被测系统扛不住而是压测机自己先怂了。你设置 2000 线程JMeter 报“无法创建线程”或者大量连接超时你以为是服务挂了结果发现是发起压测的这台 4G 内存机器先顶不住。JMeter 是纯 Java 应用高并发下需要大量堆内存存储线程状态和响应数据。默认可用的堆内存通常只有 256MB-512MB跑 500 以上线程就开始频繁 Full GCTPS 出现周期性掉坑。这个问题在笔记本电脑上非常常见。5.2 JVM 堆与 JMeter 内存配置JMeter 启动前会读取jmeter启动脚本里的HEAP参数。默认值是-Xms1g -Xmx1g -XX:MaxMetaspaceSize256m在大规模压测时远远不够。我通常会把内存调成这样export HEAP-Xms2g -Xmx4g -XX:MaxMetaspaceSize512m如果你的机器内存有 8GB建议给 JMeter 分配 4GB 堆内存在。如果压测机内存不足直接换更高配置的机器跑压测而不是在小内存机器上硬扛。判断 JMeter 是否内存不足可以开 JConsole 或者观察压测日志里的 GC 相关输出。如果发现 GC 频率高、压测过程 TPS 出现周期性归零多半是内存问题。5.3 操作系统文件句柄与端口耗尽JMeter 的每个线程通常对应到一个 Socket 连接。高并发时会有大量 TCP 连接建立和关闭Linux 系统默认的文件描述符上限ulimit -n往往是 1024超过这个数Socket 创建就会失败。压测前把文件描述符上限调高ulimit -n 65535同时还要留意 TIME_WAIT 状态堆积导致的端口耗尽问题。短连接压测时客户端端口被大量 TIME_WAIT 状态占用新连接无法建立。可以通过调整/etc/sysctl.conf来缓解net.ipv4.ip_local_port_range 1024 65535 net.ipv4.tcp_tw_reuse 1 net.ipv4.tcp_tw_recycle 0 fs.file-max 100000修改完执行sysctl -p让配置生效。这一步做不好你会发现线程数怎么加RPS 都卡在某个数值上不去而且错误日志里全是连接超时。5.4 压测前的自我检查清单综合上面说的我建议你在每次开启大规模压测之前先对 JMeter 压测机做一个“体检”内存是否足够支撑设定线程数建议堆内存不低于并发线程数 × 1MB。JVM 参数是否已经调整ulimit -n是否足够大建议 65535 以上。压测机 CPU 是否已经跑满如果压测机 CPU 已经接近 100%产物数据已经失真。压测计划中是否关闭了不能写入结果文件的“查看结果树”监听器因为高并发写文本日志也是个大坑。是否用命令行模式而非 GUI 模式执行压测GUI 模式会拖慢压测速度。正确姿势是jmeter -n -t test.jmx -l result.jtl -e -o report6. 并发设置完之后怎么判读结果、怎么调优6.1 错误率与响应时间的合理边界并发数设置正确后结果到底怎么看先看错误率再看响应时间分布最后看吞吐量。错误率不是越低越好而是要看业务约定。常规标准是错误率 0.1%部分核心链路要求 0%。如果错误率超过 1%一般视为服务不可用压测就该暂停并查日志。响应时间要看的不是平均值而是百分位值。聚合报告里的90% Line、95% Line、99% Line才有参考意义。平均值很容易被极端值带偏比如 10 个请求里一个超时 8 秒其余 9 个 50ms平均响应时间会被拉到 800ms 多看起来性能极差但实际绝大多数用户体验很好。真正的性能承诺一般以 99% Line 为准。6.2 聚合报告和监听器里到底该看什么聚合报告Aggregate Report里值得关注的字段我一般按这个顺序看Sample样本数看总请求量是否够大。样本太少结果不具备参考意义。Error%错误率先过第一道红线。Median中位响应时间反映一般用户体验。90% Line / 99% Line反映长尾用户受到的体验。Throughput每秒请求数直接对应 TPS。Received KB/sec / Sent KB/sec网络带宽。如果这个数值接近网卡上限说明网络成了瓶颈。TPS 和响应时间是一对矛盾指标。在系统资源打满之前增加并发通常会带来 TPS 上升和响应时间上升。当系统进入过载阶段后TPS 开始持平或下降而响应时间会快速抬升。你把这两个指标画成两条曲线交叉点附近的区域就是系统的“甜点区”。6.3 典型的并发设置失误与排查链路我见过不少团队压测结果忽上忽下最后发现不是被测系统的问题。常见失误集中在下面几条脚本中开了“查看结果树”且勾选“保存响应数据”。这会让 JMeter 把每个请求的响应体都写到内存和磁盘IO 开销巨大压测机反而成为瓶颈。排查方式压测时用命令行跑不打开结果树结果用聚合报告汇总。线程数设了但循环次数为 1。这会让压测在极短时间内释放全部请求后立刻结束你根本没跑到稳定状态。排查方式用-l result.jtl存结果看时间戳分布观察是否覆盖了完整的加压阶段。Ramp-Up 时间设得过长或过短。Ramp-Up 设 0 秒1000 线程瞬间全部启动对服务端的连接建立冲击很大Ramp-Up 设 300 秒线程数增长太慢短时间压测内可能没达到目标并发就结束了。排查方式结合线程活跃图观察峰值线程是否确实到了设定值。没有做数据隔离。500 个线程都用同一个用户 Token 打接口服务端可能有缓存也可能因为同一用户并发导致限流。排查方式协议日志里看是否出现缓存命中、限流错误或者唯一性校验失败。6.4 并发数不是越大越好我的真实体会最后聊点个人体会。很多刚入行的人会陷入“并发数攀比”的误区好像测出了 2000 并发就很厉害。实际上性能测试的意义在于找出系统在当前架构、当前配置下的真实容量和风险并发数只是工具参数不是成绩单。我经历过一个项目初始压测目标定为 1000 并发。我们用阶梯加压发现系统在 400 并发时响应时间还算平稳到 600 并发时 99% 响应时间直接飙到 3.8 秒触发大量超时。后来把服务端的线程池、连接池和数据库连接池重新调配之后同样的 600 并发99% 响应时间降到了 800ms 以下。整个过程JMeter 的线程数并没有改变改变的是对并发背后资源的理解。所以如果你读完这篇文章只记住一句话我希望是并发数的设置只是压测的第一步真正有价值的是理解并发背后的资源瓶颈并通过阶梯式压测找到系统的拐点。