
简介《性能测试-Jmeter.pptx》是一份面向性能测试初学者、测试工程师及培训讲师的专题课件围绕JMeter在真实项目中的落地流程展开帮助读者建立从数据准备到报告输出的完整方法框架。课件重点覆盖数据制造、性能测试方案设计、脚本执行、监控调优与测试报告编写五个环节并结合接口抓包、参数化、多线程批量造数、Jenkins持续运行、ServerAgent监控等实践细节给出可参照的操作思路与案例。压缩包共1个pptx文件大小约12.48MB便于集中学习与培训演示。目前已有1150人学习下载适合希望系统掌握JMeter性能测试流程、补齐方案设计与监控调优经验的中级测试人员查阅。1. 从空库压测说起这套 JMeter 性能测试方案要解决什么登记模块要上一版新功能验收条件只有一句话高峰期 200 个用户同时提交保存一单不超过 3 秒。真拿 JMeter 跑起来才发现开发库里的登记记录只有三千多条脚本一压响应时间 200 毫秒曲线平得像条直线。数据量不够索引走的是最优路径缓存几乎全命中测出来的只是空库的性能这个结论拿给谁看都不作数。这份性能测试培训材料最有价值的地方是把这类不显眼却关键的工作拆成了五件事造数据、设计测试方案、执行脚本、监控调优、写报告。它对应的场景包含 100 万条登记数据这样真实的量级适合正在做性能测试毕设、要交一份完整压测方案或者第一次独立接手系统压测的人。下面按这五件事的顺序往下推每一步都给到能直接照着配的参数和判断标准。2. 造数据方案100 万条登记数据的两条路与四步落地2.1 先把数据账算清初始化数据、铺底数据与参数化数据压测之前先列一份数据清单比上来就写脚本重要得多。性能测试要准备的数据分三类初始化数据是系统能跑起来的基础字典表、科室表、检查项目表这些量很小但缺一条业务就断铺底数据是历史业务数据它决定了列表查询、分页、统计报表要扫多少行参数化数据是脚本每次请求要用的唯一值登记号、患者 ID、申请单号重复一条就是一个唯一约束报错。三者的生成方式完全不同混在一起做后面排查问题时会很麻烦。以某影像登记系统为例清单上主要写了两行新建登记模块需要 100 万条登记保存模块需要 100 万条主要落在 EXAM_REQUEST、EXAM_PATIENTVISIT 这类表里。这里有一个常见误区就是把主表撑到 100 万从表还空着。从表空着的时候关联查询的执行计划和生产环境完全是两回事主表 100 万、从表 0 的关联和主表 100 万、从表 300 万优化器选的路可能完全相反测出来的响应时间没有参考价值。我一般会把主从表的比例一起写进清单比如申请单和就诊记录按 1:1 铺避免压测时出现“主表很重、从表很轻”的假象。还有一点容易被忽略铺底数据的时间分布。如果 100 万条全落在同一个小时里按时间范围查询的条件几乎命中全表和真实业务里数据按天均匀分布的表现差很远。通常的做法是按天、按月打散最近三个月的密一些更早的稀一些这样统计类接口的耗时才有参考意义。2.2 走 HTTP 接口造数抓包到批量执行的四步第一种造数方式是让 JMeter 模拟真实 HTTP 请求往接口打数据。它的好处是不用理会数据库表之间的关联关系业务代码会帮你把该写的表都写对造出来的数据跟真人操作出来的没差别代价是速度慢一点一小时大概 2 万到 5 万条。整个过程可以拆成四步。第一步用抓包工具把登记保存接口的请求抓出来拿到 URL、请求头、表单或 JSON 里的全部参数。第二步把每单必须变的字段参数化比如登记号、患者 ID、就诊号、检查项目、申请时间。第三步先设 10 个线程跑一轮看聚合报告里的错误率是不是 0再去数据库里数一遍条数对不对。第四步确认没问题再放大批量。参数化不一定要维护一个百万行的 CSV。百万行 CSV 光是读文件就拖慢脚本维护起来也难受用 JMeter 内置函数拼唯一值更省事登记号REG${__time(yyyyMMddHHmmss,)}${__threadNum()}${__counter(FALSE,)} 患者IDP${__threadNum()}${__counter(FALSE,)} 申请时间${__time(yyyy-MM-dd HH:mm:ss,)}__time取当前时间戳保证跨批次不重复__threadNum取当前线程编号把不同线程的值岔开__counter是线程内自增保证同一个线程连续跑几万次也不会撞号。这三段拼起来唯一性基本够用脚本也不用依赖外部文件。如果业务字段必须从固定集合里取比如检查项目只能从 CT、MR、DR 里选那用 CSV Data Set Config 挂一个小文件就够了几十行足够循环使用不要为了“看起来真实”去造百万行静态数据。线程组的关键参数按这个配线程数 20循环次数 50000调度器不勾选Ramp-up 设 60 秒让压力缓慢加上去。20 乘 50000 正好 100 万Ramp-up 给足是为了避免脚本一启动 20 个线程同时抢同一批序列或同一把锁。提示第三步的调试不能省。10 个线程跑完一定要去数据库里select count(*)核对条数同时看 EXAM_PATIENTVISIT 里有没有对应记录。只盯 JMeter 的聚合报告会出现“请求全成功、数据没落库”的情况比如接口异步写库、消息队列堆积报告上一点错都没有。2.3 存储过程与代码直插快 5 倍但要对表关系负责第二种方式是绕过接口直接用存储过程或者一段 Java 代码往表里插数据。速度能到一小时 10 万到 20 万条是接口造数的几倍但前提是你得把表之间的关联关系摸清楚SQL 写错就是一批脏数据清理起来比重造还费时间。Oracle 下的存储过程大概是这个形状-- 每次调用插入 300 条登记申请循环结束统一提交 create or replace procedure T_EXAM_REQ_SP as begin for i in 1 .. 300 loop insert into EXAM_REQUEST( REQUEST_ID, VERSION, PATIENT_ID, VISIT_ID, EXAM_ITEM_CODE, REQUEST_TIME, STATUS ) values ( sys_guid(), -- 主键用 GUID避免并发撞号 1.0, P || lpad(i, 8, 0), -- 患者号补零对齐 V || lpad(i, 8, 0), -- 就诊号与患者号一一对应 CT_HEAD, sysdate, 1 ); end loop; commit; -- 提交放在循环外减少日志刷盘 end; /几个参数值得说清楚。sys_guid()生成 32 位主键比自增序列更适合并发插入lpad(i, 8, 0)把序号补成定长字符串患者号和就诊号按同一套规则生成后面写从表时能直接对应上commit放在end loop外面而不是循环里是因为每插一行提交一次会让 redo 日志频繁刷盘速度掉一半以上。真要提速还可以用insert into ... select ... from dual connect by level 300的批量写法一次插入三百行。选哪条路判断标准其实很朴素表关系清楚、时间紧就走存储过程表关系不清楚、或者要求数据必须经过业务校验比如状态机、审批流就走接口。我在这个项目里选的是接口造数原因很直接影像系统的表关系没人能一次讲明白而造数的时间还算充裕宁可慢一点也不要事后清脏数据。2.4 放到 Jenkins 上长跑线程数、循环次数与时长换算100 万条按一小时 2 万到 5 万条算需要连续跑 20 到 50 小时也就是一到两天。这个时长决定了脚本不能放在本地机器上跑因为没人能保证两天不关机、不断网、不锁屏。放到 Jenkins 上做成定时任务是这类长耗时造数最稳的做法。命令行执行的方式比开 GUI 靠谱得多# 非 GUI 模式执行造数脚本结果写 jtl同时生成 HTML 报告 jmeter -n -t exam_create.jmx \ -l result_$(date %Y%m%d%H%M).jtl \ -e -o report_$(date %Y%m%d%H%M) \ -Jthreads20 -Jloops50000-n表示不开图形界面GUI 模式本身吃内存跑长任务容易卡死-t指定 jmx 脚本-l是结果文件文件名带时间戳方便分批留存-e -o让 JMeter 直接生成 HTML 报告不用再拿 jtl 去二次处理-J开头的参数是传给脚本的全局属性线程数和循环次数写在命令行里改量级时不用动脚本。如果一次跑不完就拆成多个批次Jenkins 里配一个每两小时触发一次的定时任务每批跑 10 万条跑完记录当前已造条数。这样中途失败了可以从断点续不至于 40 小时的活儿在最后一小时崩掉重来。JMeter 版本要保持一致客户端和 Jenkins 上都用同一个版本避免同一个脚本在两边表现不一样。3. 性能测试方案设计需求规格、三机环境与场景建模3.1 把性能需求规格落成可测的数字项目组给的性能需求规格说明书通常就一句话系统应支持 200 用户并发响应时间不超过 3 秒。这句话不能直接拿去配线程组得拆成五个能落到脚本里的量并发用户数、事务响应时间看 90% 线而不是平均值、TPS、错误率、持续时长。少一个测试结果就没法判定通过还是不通过。响应时间为什么看 90% 线这里得说清楚。平均值会被少量极快的请求拉低200 个用户里有 180 个 300 毫秒、20 个 8 秒平均值可能只有 1 秒出头看起来达标了但那 20 个人的体验是崩溃的。90% 线能把这部分长尾露出来通常还会同时看 95% 和最大值。思考时间也得写进方案。200 个线程如果不设思考时间等于 200 个用户一秒钟点十几次这不是真实操作节奏测出来必然超标。一般按业务实际操作间隔设 3 到 5 秒用 JMeter 的 Constant Timer 挂在请求下面。反过来如果需求写的是“峰值 TPS 不低于 500”那思考时间就要反过来算从 TPS 推线程数而不是从线程数推 TPS。验收标准的写法我一般是这样在 200 并发、思考时间 3 秒、持续 30 分钟的条件下登记保存事务的 90% 响应时间不超过 3 秒TPS 不低于 60错误率为 0服务端 CPU 平均使用率低于 70%。四个数字加一个资源水位才是一份能签字的判定条件。3.2 三机环境清单客户端、应用服务器、数据库服务器环境不说清楚测试结果就没有可比性。方案里必须列出每台机器的 IP、硬件配置和软件版本客户端、应用服务器、数据库服务器三台分开写。下面是这个项目的实际清单可以直接当模板改。服务器类型IPCPU内存硬盘操作系统测试客户端10.1.1.18016 核8G500GWindows 10应用服务器10.8.3.19916 核64G500GWindows Server 2012 R2数据库服务器10.8.3.17316 核64G500GWindows Server 2012 R2服务器类型软件配置测试客户端Windows 10 SP1 64 位JMeter 5.1.1 及 ServerAgent应用服务器JDK 1.8Tomcat 8.0Nginx 1.10数据库服务器Oracle 19c客户端只有 8G 内存这一点要特别注意。JMeter 是 Java 程序200 个线程加上聚合报告和监听器堆内存很容易吃满压测机自己先成瓶颈表现出来的现象是响应时间随并发上升暴涨但服务端 CPU 才 20%。所以方案里要写清楚客户端 JVM 堆参数比如-Xms2g -Xmx4g并且长跑一律用非 GUI 模式。3.3 监控指标与采集方式对照表只压不监控等于把系统当黑匣子出了问题只能猜。方案里要把指标、参考值和采集方式一一对应写出来执行的时候照着这张表挨个确认。指标名称参考值说明监测方式并发用户数按场景设定线程组中的线程数JMeter事务响应时间90% 线 ≤ 3s每笔事务的平均响应时间变化JMeter 聚合报告事务成功率错误率为 0错误率非 0 说明有请求失败JMeter 聚合报告CPU 使用率平均 70%关注是否长期满载ServerAgent PerfMon内存使用率压后能回落关注 Full GC 后是否恢复ServerAgent PerfMon数据库 Top SQL无全表扫描找出耗时或耗资源最多的 SQLAWR系统整体负载—数据库整体处理情况AWR、ADDM这张表的价值在于它把“测什么”和“用什么测”绑在一起。执行阶段一旦发现某一项没有数据立刻能定位是采集端没装还是端口没通不用等测试结束再回头补。3.4 业务场景建模从单接口到混合业务比例场景不能只测一个接口。性能问题大多出现在多个业务抢同一批资源的时候单接口跑得再漂亮混合场景一样可能崩。我一般按四层往上叠第一层是单接口基准只压登记保存确认脚本本身没问题拿到一个基线值第二层是单业务场景把登记模块的完整链路串起来包括打开页面、查询、保存第三层是混合场景按生产实际的业务比例配比如登记 40%、查询 40%、报告打印 20%用不同的线程组按比例分配线程数第四层是稳定性场景取峰值压力的 70% 到 80%连续跑 8 小时专门看内存泄漏和连接池耗尽这类慢问题。混合比例不是拍脑袋定的可以从生产日志或者数据库里统计一段时间内的接口调用次数按比例折算成线程数。这一步做扎实了测试结果的说服力完全不一样答辩时被问“你这个比例哪来的”能直接拿出统计口径。4. 脚本执行控制器、集合点与服务端监控的接入顺序4.1 用例化命名与控制器选型脚本要按测试用例的方式组织一个用例一个简单控制器或者事务控制器名字写成“登记保存-单笔-正常流程”这种能看懂的格式不要留 Sampler 的默认名。后面出报告、看聚合报告、定位问题时你靠的就是这些名字。控制器的选型只有一条判断请求之间有没有先后依赖。几个请求可以同时发、互不依赖用简单控制器把它们归个组就行请求之间有严格先后顺序而且要把整体耗时算成一笔事务就用事务控制器它会把下面所有请求的耗时合并成一个“事务响应时间”。比如“打开登记页 → 填写信息 → 点击保存”这三步业务上是一笔完整操作必须用事务控制器包起来否则聚合报告里看到的是三个独立请求的耗时跟需求里的“保存一单不超过 3 秒”对不上。事务控制器的Generate parent sample要勾上这样报告里只出现事务本身的统计子请求的数据不会混进来干扰判断。同时把Include duration of timer and pre-post processors in generated sample也勾上思考时间和前置处理器的耗时才会被算进去这更接近用户真实感受到的等待。4.2 同步定时器集合点放在请求之前还是之后同步定时器模拟的是集合点让指定数量的线程攒够了一起发。位置很关键放在事务控制器内部、具体请求之前攒的是请求放在事务控制器外面攒的是整个事务。压登记保存接口一般放在保存请求前面让 200 个线程同时打这一下才能测出数据库瞬时写入的极限。配置上两个参数要配对Number of Simulated Users to Group by填集合的线程数通常等于线程组总数Timeout in milliseconds一定要填比如 10000。超时设 0 表示无限等一旦集合数大于实际线程数脚本会永远卡在那里不结束现象是压测跑了半小时一个请求都没发出去很多人第一次遇到会以为是网络问题。还要注意集合点和 Ramp-up 的关系。线程组 Ramp-up 设了 60 秒线程是慢慢起来的前几个线程到集合点会一直等到凑够人数或者超时这段时间的响应时间会把统计拉高。所以用集合点的场景Ramp-up 要么设小一点要么在正式计时前先预热一轮。4.3 ServerAgent 与 PerfMon4444 端口这条链路服务端的 CPU 和内存数据靠 JMeter 插件 PerfMon Metrics Collector 采集被采集的机器上要先跑一个 ServerAgent。Windows 服务器双击startAgent.batLinux 服务器执行startAgent.sh默认监听 4444 端口。# Linux 服务端启动采集代理默认端口 4444 nohup ./startAgent.sh --udp-port 0 --tcp-port 4444 agent.log 21 # 从压测机确认端口通不通不通的话后面所有监控都是 0 telnet 10.8.3.199 4444--udp-port 0表示关掉 UDP只保留 TCP避免某些网络环境把 UDP 包丢掉导致曲线断断续续nohup ... 让它后台常驻日志重定向到文件方便排查telnet那一步是最容易被跳过的一步端口不通的话 PerfMon 界面上全是 0看起来像“服务端一点压力都没有”实际是根本没采到数。PerfMon 插件是 JMeter 的可选插件需要单独下载安装装完重启 JMeter 才能在监听器里看到。添加监听器后主机填服务端 IP端口 4444指标勾 CPU、Memory、Disks I/O 三项就够用。如果网络确实不通换 nmon 之类的工具在服务端本地采集测完把文件拿回来分析别硬等端口打通。4.4 JConsole 远程连接与 Oracle 手工快照应用服务器是 TomcatJVM 层面的问题要靠 JConsole 看。先在服务端开启远程 JMX 端口启动参数里加上# Tomcat 启动参数中追加 JMX 远程配置 -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port9004 \ -Dcom.sun.management.jmxremote.authenticatefalse \ -Dcom.sun.management.jmxremote.sslfalse \ -Djava.rmi.server.hostname10.8.3.199port是 JMX 监听端口authenticatefalse和sslfalse是内网测试环境为了省事关掉鉴权生产环境不能这么干java.rmi.server.hostname必须写服务端的实际 IP不写的话 JConsole 能连上但拿不到数据这是很典型的一个坑。本地打开 JConsole输入10.8.3.199:9004就能远程连上去。JConsole 主要看两个页签。内存页签相当于可视化的 jstat看堆内存曲线在每次 Full GC 后能不能回到原位线程页签相当于可视化的 jstack遇到线程长时间停顿就看这里常见的原因有三类等外部资源数据库连接、网络、设备、死循环、锁等待活锁和死锁。数据库侧靠 AWR。AWR 默认一小时自动打一次快照压测场景如果只有十几分钟很可能整段都落在一个快照区间里报告里什么都看不出来。所以复杂场景要在执行前后各手工打一次快照-- 场景开始前和执行结束后各执行一次把测试时段卡出来 exec DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT(); -- 生成 AWR 报告按提示选择刚才两个快照的起止编号 ?/RDBMS/ADMIN/awrrpt.sql; -- 11g 需要额外跑 ADDM 拿优化建议19c 两个脚本已合并不用单独执行 ?/RDBMS/ADMIN/addmrpt.sql;?代表 Oracle 的安装目录在 sqlplus 里能直接识别。选择快照编号时一定要挑测试时段对应的那两个选错了报告里全是业务低峰的闲时数据看不出任何问题。场景简单、执行时间短的话也可以等全部跑完再一次性生成报告但多个场景混在一个区间里就分不清瓶颈是哪个场景引入的。5. 瓶颈排查与常见翻车点从日志关键字到五条踩坑记录5.1 日志关键字四类异常先定位方向日志是系统异常最直接的反映客户端和服务端的日志一起看能很快把范围缩小。大用户量、大并发下才会暴露的问题往往也只在错误日志里出现。有几个关键字基本一眼就能定性OutOfMemoryError或Cannot allocate memoryJVM 内存溢出往堆大小、内存泄漏方向查SQLException数据库语句执行异常日志里通常还带着数据库返回的错误码直接看是语法、锁等待还是连接问题Connection closed或connection refused连接被关闭或被拒绝基本是连接数扛不住当前压力去查连接池上限和数据库最大连接数。排查顺序建议从日志开始再往资源和中间件走最后才落到 SQL。反过来先怀疑 SQL很容易在一堆慢查询里绕不出来而真正的原因可能是 Tomcat 线程池只有 200 个200 并发时请求全在排队。5.2 CPU 三分法User、Sys、Wait 分开看CPU 占用率高不一定是问题压测的目的本来就是榨干硬件。但如果长期在 80% 以上就说明计算能力已经成了瓶颈。更关键的是看 CPU 时间花在哪User 高说明是业务代码在算看看有没有低效循环、正则、大对象序列化Sys 高说明是系统调用多常见于频繁的线程切换、大量的文件或网络 I/OWait 高说明 CPU 在等外部资源这时候要去看磁盘 I/O。一个很典型的场景某张大表查询没走索引全表扫描导致大量物理读CPU 有 80% 以上处于 Wait 状态看 CPU 总使用率很高其实是 I/O 在拖后腿。这种情况加机器没用得回去补索引或者改 SQL。5.3 内存泄漏判定看 Full GC 后能不能回落内存问题主要看 JVM判断依据很直接每次 Full GC 之后已用内存能不能回到之前的水平。如果曲线是阶梯状往上走每次 Full GC 只回落一点点压力撤掉一段时间后内存依旧不降那基本可以判定存在内存泄漏这时候用 jmap 导出堆快照看哪个对象占得最多。反过来如果压力撤除后内存能顺利回落只是压测期间占用高那是正常的对象分配不是泄漏不用改代码把堆调大或者优化对象生命周期就够了。这两者搞混会导致在没必要的地方做大改。5.4 五条最容易翻车的点第一条造数脚本错误率 30%但数据库条数对不上。现象是聚合报告一片红接口返回唯一约束冲突。原因是参数化用了固定值或者__counter没加线程前缀多个线程生成了同一批单号。解决是把线程号和计数器拼进唯一字段跑之前先 10 线程小批量验证跑完立刻select count(*)核对。第二条PerfMon 曲线全是 0服务端看起来毫无压力。现象是压测期间 CPU 内存两条线贴地。原因八成是 4444 端口不通或者 ServerAgent 根本没起。解决是先 telnet 确认端口再检查 agent 进程两者都通还采不到就换 nmon 本地采集。第三条脚本跑到一半卡死不动。现象是压测开始了半小时一个请求都没发出去日志里也没报错。原因是同步定时器的集合数大于实际线程数超时又设成了 0。解决是把超时改成 10000 毫秒并确认集合数不超过线程组总数。第四条AWR 报告里全是闲时数据。现象是报告显示数据库负载极低跟压测时的表现完全相反。原因是 AWR 默认一小时一次快照十几分钟的场景被夹在两个快照中间或者选错了快照编号。解决是场景前后各手工CREATE_SNAPSHOT()一次生成报告时严格按测试时段的编号选。第五条压测机自己先成为瓶颈。现象是并发一加上去响应时间就暴涨但服务端 CPU 只有 20%网络也不忙。原因是 JMeter 开着 GUI 跑、堆内存不够、或者监听器挂了太多吃内存的组件。解决是改用-n非 GUI 模式客户端堆调到 4G聚合报告只留必要的几个压测机和被测服务分开部署。6. 报告与验收把聚合报告讲成一份能签字的结论性能测试报告不是把截图堆上去就完事它要能回答三个问题测了什么、结果如何、瓶颈在哪。我一般按五块组织测试目的与范围写清楚覆盖了哪几个模块、不覆盖什么测试环境三机配置表和软件版本原样贴上去这是结果可比性的前提测试场景与数据量把并发数、思考时间、持续时长、铺底数据量列成表测试结果聚合报告的响应时间、TPS、错误率配 PerfMon 的 CPU 内存曲线和 AWR 的关键指标瓶颈分析与建议每一条都要有证据支撑日志片段、Top SQL、线程栈都行。章节写什么拿什么当证据测试目的与范围覆盖模块、验收指标性能需求规格条目测试环境三机硬件与软件配置配置清单表场景与数据量并发数、时长、数据规模线程组配置、造数记录测试结果响应时间、TPS、错误率、资源水位聚合报告、PerfMon 曲线、AWR瓶颈与建议问题定位、优化方向日志片段、Top SQL、线程栈答辩或者评审时最常被追问的就三个点数据量到底够不够瓶颈证据在哪结论是怎么推出来的。第一个用造数记录和数据库条数回答第二个用监控曲线和日志关键字回答别只说“感觉是数据库慢”第三个把验收标准和实测值并排放达标就是达标不达标就给出优化项和复测计划。有一次我图省事场景跑完才想起来没打 AWR 快照报告里数据库那段只能拿应用日志硬凑评审时被连着问了三个问题都答不上来最后整场重跑。从那以后我每次执行场景前都强制走一遍清单快照打了吗、ServerAgent 通吗、JConsole 连上了吗、结果文件命名对吗四项全勾上才开始压。希望帮到你。本文还有配套的精品资源点击获取