简介:针对APP后台服务器进行性能压测的实战文档,面向测试工程师、性能测试新手及移动应用后端开发者。该方案巧妙结合LoadRunner12的App脚本录制能力与LoadRunner11的免费高并发支持,先用LR12录制、调试脚本,再放到LR11执行压测,LR11破解版最高可支撑6.5万并发,弥补了单版本工具在移动端压测上的短板。文档从LoadRunner简介、环境准备、手机WiFi代理设置、Remote Application via LoadRunner Proxy录制、脚本Debug与异常行处理,到LR11安装破解、运行脚本及结果分析,形成完整操作链路。整套资源以1个docx文档提供,共1个文件,压缩包约691KB,步骤清晰,适合边看边操作。目前已有555人学习下载,可帮助读者快速搭建APP后端压测环境并掌握关键排错思路。
1. 双版本组合压测:这套 LoadRunner APP 压测方案为什么值得一试
多数人以为 LoadRunner 是 Web 压测的专属工具,碰到移动端 APP 后台接口就直接转投 JMeter 或自研脚本。但如果你手里只有 LoadRunner 授权、团队也习惯了 LR 的操作流,那这套「LR12 录脚本 + LR11 跑并发」的组合方案就是一条性价比极高的野路子。它的核心思路很简单:LR12 社区版免费、能录手机 APP 的代理请求,虽然只支持 50 个并发;LR11 有通用 license、能跑到 6.5W 虚拟用户,但不支持 APP 录制。把两者拼在一起,等于用免费工具补上了付费工具的功能缺口。这套流程我在模拟项目X的实际压测里完整跑过,对后端接口的请求抓取、脚本清洗、并发施压和结果分析都有可复现的路径,适合正在做移动端服务端性能验证的测试和开发人员。
2. 环境准备与链路搭建:先把代理录制这条数据管道打通
2.1 为什么要用代理模式录制 APP 请求
移动端 APP 和 Web 页面的最大区别在于:Web 端可以通过浏览器插件或网关直接捕获 HTTP/HTTPS 流量,而 APP 的请求大多走 HTTPS 加密通道,普通录制工具只能看到一堆乱码或直接断连。LR12 社区版提供的解决思路是「中间人代理」——在电脑上开一个监听端口,手机把代理指向这台电脑,所有 APP 请求都会经过这个端口转发到后端服务器,LR12 在这个过程中把请求内容解析并记录成脚本。
这套录制链路里三个角色缺一不可:电脑端的代理监听服务、手机端的代理设置、以及 APP 本身可操作的业务流程。我一般会在开始录制前先确认手机和电脑在同一网段,并且电脑防火墙放行了代理端口,否则会出现「录制启动但抓不到任何包」的典型症状。
2.2 在 LR12 里创建 APP 录制脚本的完整步骤
先装好 LR12 社区版,安装路径不要带中文,这个版本安装完成后会有 Virtual User Generator、Controller、Analysis 三个独立入口。社区版的 Controller 和 Analysis 因为并发限制基本用不上,整个方案里只有 Virtual User Generator 是核心工具。下面是我在 64 位 Windows 7 环境里的操作步骤:
第一步,打开 Virtual User Generator,点击 Create 新建脚本时选择Web - HTTP/HTML协议,不要选 Mobile 协议——后面会解释为什么。
第二步,点击 Record 按钮后,在弹出窗口里把 Recording Mode 切换到Remote Application via LoadRunner Proxy,端口填一个不冲突的四位数,比如 8899。
第三步,把手机 Wi-Fi 代理设置为电脑的局域网 IP 和同样的端口号,然后启动录制,在手机上完整操作一遍 APP 的核心业务路径,点 Stop 结束录制。
# 验证电脑端口是否已监听(Win 7 下用 netstat 命令) netstat -ano | findstr 8899 # 预期输出中出现 LISTENING 状态,说明 LR12 代理已就绪第四步,录制完成后的脚本会在 Vugen 里以树形结构展示每个请求,先点击 Replay 跑一遍冒烟回放,确认事务能否通过。
第五步,回放失败的话打开 Replay Log 定位报错的行,多数情况下是请求了第三方统计 SDK 或推送通道,这些在测试环境没有回包,可以直接从脚本里删掉,不影响主流程。
这里有个关键点:选择 Web - HTTP/HTML 协议而不是 Mobile 协议。LR12 的 Mobile 录制协议依赖模拟器或真机调试通道,配置成本高且不稳定;而通过代理方式录制时,APP 请求本质上是 HTTP/HTTPS 报文,Web 协议恰好能完整捕获并解析。我在实测中发现,Mobile 协议在部分安卓机型上会出现握手失败,而 Web 协议走代理反而稳定得多。
2.3 录制链路中容易翻车的三个前置条件
录制链路有三个前置条件,任何一个不满足都会导致录制失败或脚本缺请求,按重要性排序如下:
第一,手机和电脑必须在同一局域网内,且电脑的局域网防火墙对代理端口放行。操作路径是「控制面板 → Windows 防火墙 → 高级设置 → 入站规则 → 新建规则 → 端口」,把 8899 加入允许列表。
第二,代理端口不要用 8080、8000 这类常见端口,部分 APP 或系统组件会默认走 8080 而不是走代理,设置一个生僻的四位数端口能避开这类冲突。
第三,APP 证书信任问题。如果 APP 做了 SSL Pinning(证书锁定),代理方式抓到的请求会被客户端直接拒绝。测试环境可以要求开发提供一份关闭 Pinning 的调试包,这个问题无解。
注意:录制出来的脚本里数字签名或加密字段的请求体可能是乱码,这类请求在 LR11 回放时也大概率失败。如果只是压测核心业务链路,优先删掉;如果是压测上传接口,需要开发配合把加密改成可配置的测试密钥。
3. 脚本整理:把录制产物从「能回放」整到「能压测」
3.1 清洗脚本中的杂散请求与动态参数
录制完成的脚本通常包含三类请求:核心业务请求、资源文件请求(图片、CSS、JS)、第三方 SDK 上报请求。这三类在压测场景里的地位完全不同——核心业务请求才是测试目标,资源请求会在并发时制造大量无意义的流量干扰指标,SDK 上报请求则因为缺少真实服务器而频繁报错。
我的清洗策略是这样的:先把录制日志里的 URL 列表导出来,按域名或路径前缀做一次粗分类,业务接口保留、静态资源直接删除、第三方域名全部剔除。删除操作在 Vugen 的 Tree View 里勾选对应节点执行 Delete 即可。
动参处理是另一个重点。同一个用户操作里,token、sessionId、时间戳、随机数都会变化,录制脚本里的值是写死的,并发回放时必然出现鉴权失败或业务校验失败。处理方式分两步:第一步,用 Vugen 的 Scan for Correlations 功能自动扫描动态值;第二步,手动把扫描结果里的关键参数(特别是鉴权头里的 token)替换成关联函数生成的变量。
// LR 脚本中动态 token 的关联写法示例 web_reg_save_param("token_param", "LB=Authorization: Bearer ", "RB=\n", "Search=Headers", LAST);这段代码的意思是把上一个请求响应头里Authorization: Bearer到换行符之间的内容存入token_param变量,后续请求的 Headers 里直接引用{token_param}。我在多个项目里验证过,登录接口的 token 用这种方式关联后,回放成功率能稳定在 90% 以上(排除验证码拦截的情况)。
3.2 对加密和签名参数做全局替换
如果 APP 对请求体做了整体加密(比如 JSON 字段被 AES 或 RSA 包裹),录制脚本里看到的就是一段密文,回放时这段密文大概率已经过期或签名校验失败。这种场景下常规关联手段是不够的,我会和开发确认一下加密逻辑,确认能否支持「测试模式」绕过或固定密钥。
常见的做法是:让开发在测试环境里把加密开关关掉,或者提供一个预置的协议头标记(比如X-Test-Mode: 1)让服务端跳过签名校验。如果这两条路都走不通,还有一条退路:用代码里自己算出的签名替换掉录制脚本里的签名。
// 用 LR 内置加密函数重新计算签名(以 MD5 为例) sprintf(sign_value, "%s%s%s", "app_key=test", "timestamp={time}", "salt=salt123"); md5_hash(sign_value, sign_result); lr_save_string(sign_result, "sign"); web_add_header("X-Sign", "{sign}");这段脚本在实际项目中能解决很大一部分签名问题,难点在于 MD5 前的拼接规则必须和 APP 源码里的完全一致,否则就会产生「回放成功但业务失败」的假象。我会拿着这份拼接逻辑找开发对一遍,确认无误后再进入压测。
3.3 脚本在 LR12 录制、LR11 回放的兼容性验证
LR12 录制的脚本默认保存格式是 .usr,但脚本内部的事务函数、web_url、web_custom_request 等核心 API 和 LR11 是兼容的,我实测验证过可以直接运行。唯一的坑在于:LR12 生成的脚本里可能会引用新版本才有的函数库,LR11 打开时会报「function not found」。
处理对策比较直接:在 LR12 里把脚本里的这些函数替换成 LR11 通用的等价函数。最常遇到的是web_cache_cleanup和web_cleanup_auto_cookies这两个函数在 LR11.0 的某些补丁包里不可用,直接删掉或注释掉即可,它们只负责缓存清理和 Cookie 状态维护,不影响基本压测逻辑。
4. 载荷与场景配置:把并发数、迭代时长和思考时间调成合理值
4.1 理解虚拟用户数、迭代次数和持续时间的关系
LR11 的 Controller 里压测场景有三个核心旋钮,很多人拧错方向就是没搞清这三者的逻辑关系:
虚拟用户数(Vusers)决定的是同一时刻的并发请求数,迭代次数(Iterations)决定每个虚拟用户循环执行脚本的次数,持续时间(Duration)则规定了整个压测跑多久。三者互相影响,比如设定 100 个用户持续 30 分钟后,系统吞吐量除了受用户数影响,还受每个用户的思考时间(Think Time)影响——思考时间越短,单用户的请求密度越高,后端承受的压力也就越大。
实际压测中我通常把场景配成「按持续时间跑」而不是「按迭代次数跑」,因为持续模式能让负载曲线更平滑,结果也更稳定。设置入口在 Controller 的 Schedule Builder 里,把 Duration 设置为 15 到 30 分钟,并勾选「持续直到完成」。
4.2 运行时设置里有三个最值得改动的参数
进入 Vugen 的 Runtime Settings 后,我基本只动三个页签:General里的 Think Time、Internet Protocol里的 Preferences、以及Pacing里的迭代间隔。
先说 Think Time,录制时 LR 会把你在 APP 里慢悠悠操作的时间差都记录成思考时间,压测时如果保留这个值,虚拟用户按下单按钮后可能会等上几秒钟才发下一个请求,后端根本看不到压力。压测执行时我一般把思考时间设置为「忽略(Ignore)」,让请求以最快的节奏打过去。如果你想模拟更真实的用户行为,可以把思考时间压缩到录制值的 20%~50% 之间。
再说Pacing,这个参数控制每次迭代结束到下一次迭代开始之间的间隔。压测时我会设置成「不等待(As soon as possible)」,除非你明确要做固定速率加压测试。
最后说Internet Protocol里的Preferences,这个页签里可以设置 HTTP 请求的超时时间,在弱网或慢接口的压测场景里,默认的 120 秒超时可能掩盖真正的响应延迟。我一般会把连接超时设置为 10 秒,数据接收超时设置为 30 秒,这样能更快暴露接口异常。
4.3 场景加载策略:从少量用户起步再逐步加压
场景配置里最常见的失误是一上来就拉满 6000 个用户,结果服务端直接雪崩,连错误日志都来不及记录。我的习惯是先跑一轮 10 用户的冒烟场景,确认脚本回放通过率和业务成功率都正常后,再按阶梯式加压:50 → 200 → 500 → 1000。每个台阶维持 3 到 5 分钟,观察吞吐量和错误率的变化。
LR11 的 Controller 里配置阶梯加压的地方在Schedule Builder的Ramp Up区域,设置好初始用户数、每步增加的用户数以及步长间隔后,工具会自动生成一个负载曲线。我一般把 Ramp Up 设置为每 30 秒增加 100 个虚拟用户,这样后端有充分的时间做连接池扩容和缓存预热,不会因为瞬时流量过大而误报「服务不可用」。
5. 执行与避坑:LR11 跑并发时的 Licence、报错和结果解读
5.1 安装破解与并发上限的边界
LR11 的安装流程比 LR12 更敏感,我遇到的第一个坑是安装路径带中文导致安装直接回滚,换成纯英文路径后一次通过。第二个坑是替换 .dll 文件时操作系统自带杀毒软件把补丁文件直接隔离,导致启动时报找不到 license。解决方法是安装前先把实时防护关掉,替换完成后再打开,并把补丁文件所在目录加入白名单。
license 这块需要特别冷静地看待:网上流传的「6.5W 并发」是一个理论峰值,实际达到这个规模需要 License 里有足够数量的 Virtual User 授权。我在实际项目中用到的最大的并发规模是 8000,超过这个量级后 LR11 Controller 本身所在机器的内存和网络连接数会成为瓶颈。CI 环境压测时,Controller 机器和 Load Generator 机器最好分开部署。
5.2 高频踩坑:回放失败、压测白屏、请求响应全乱码
我在多个项目里总结出的高频踩坑记录如下:
坑一:LR12 录制好的脚本在 LR11 回放时 HTTP 500 或 502现象:脚本在 LR12 里回放通过,在 LR11 里跑到一半突然报 HTTP 500,重启 Load Generator 后又恢复正常,但过几分钟再报同样错误。 原因:LR11 自带的 Load Generator 和 Controller 之间通过 socket 通信,当并发数攀升时 Controller 和 Generator 的 TCP 连接数达到系统上限,触发服务端反压。 解决:在 Load Generator 所在机器上调整注册表里的 TCP 连接数限制(TcpNumConnections项),并确保防火墙放行了 LR 的通信端口;同时把多个 Generator 做负载均衡,不要把并发全部压在一台机器上。
坑二:压测跑完后 Analysis 报告里的响应时间呈直线上升现象:平均响应时间从 50ms 一路涨到 5000ms,但错误率一直是 0。 原因:持续压测导致后端连接池或线程池耗尽,请求在排队而没有被拒绝,所以错误率为 0 但有明显的「响应时间拐点」。 解决:把场景的持续时间拉长到 20 分钟以上,再去观察响应时间的分位数(90th/95th/99th),单纯看平均值会被少量长尾拖垮;建议把 95th 响应时间作为主要判定指标。
坑三:并发一超过 50 个就报「License 不够」——明明用的 LR11现象:LR11 控制台里已经导入了 license,但只要设置超过 50 个虚拟用户就报错,提示 No license available。 原因:Controller 默认连接到了 LR12 社区版的 Load Generator 组件,而社区版 License 的硬限制就是 50 用户。 解决:把压测任务的 Generator 指定到 LR11 安装目录下的bin\mdrv.exe服务,或者干脆卸载 LR12 的 Controller 组件,只保留 Vugen,再重新指定 Generator。这是我踩过最狠的坑,连着两版 PRESS 任务都栽在这里。
坑四:录制的 HTTPS 请求是加密乱码现象:脚本里看到的核心业务请求不是正常 URL,而是一串看不懂的二进制密文,回放后 APP 端直接登出。 原因:录制时 APP 的 SSL 层与 LR12 代理未能完成证书信任握手,LR12 只能录制到加密套接字内容。 解决:把 APP 的测试包切换到 HTTP 明文协议,或者在手机里安装 LR12 自带的根证书(录制盒里有 Import CA Certificate 入口)。强烈建议压测环境用 HTTP 明文,省去大半证书烦恼。
5.3 如何把 Analysis 里的指标转换成有说服力的压测报告
压测执行完毕后,Analysis 工具会自动汇总出 Hits/Sec、Transaction Response Time、Errors 等指标。但直接把这些原始图表丢给开发或领导,基本没说服力。我自己的做法是:先导出 Transactions 和 Web Resources 两个页签的数据,做三组关键对比:
第一组是「并发数 vs 吞吐量」曲线,观察在哪个并发点出现瓶颈;第二组是「并发数 vs 响应时间 95th 分位」曲线,找出性能拐点;第三组是「错误率 vs 时间」曲线,确认压测全程没有阶段性的抖动。
// 导出后按时间戳对齐的示例指标数据(真实数据脱敏) 时间,虚拟用户数,吞吐量(byte/s),平均响应时间(ms),95th响应时间(ms),错误率(%) 00:00,50,1024,82,120,0.0 05:00,200,4096,150,360,0.2 10:00,500,5200,880,2400,1.8把这三组数据整理成表格后,报告的结论自然就出来了:哪个接口是瓶颈、系统能支持多少并发、最大吞吐是多少。比粘贴一张原始趋势图直观得多。
6. 两个高阶技巧:把 LR 这套组合方案用得更顺手
6.1 用参数化文件模拟多用户真实负载
录制脚本里如果存在用户维度的数据(比如每个用户有自己的订单号和收货地址),直接并发时会因为数据冲突产生大量业务失败。解决思路是准备一个 CSV 参数文件,让每个虚拟用户从文件里读取自己的凭证,同一用户的数据在整个压测过程中保持一致。
// 参数化文件 parm_user.csv 的内容格式 user_id,token u1001,a1b2c3 u1002,d4e5f6 u1003,g7h8i9 // 脚本中的引用方式 web_add_header("Authorization", "Bearer {token}"); web_url("order", "URL=http://api.test.internal/order/{user_id}", "TargetFrame=", "Resource=0", LAST);参数化文件里放多少行数据决定了虚拟用户最多有多少个「独立身份」。压测 5000 并发时如果只准备了 100 个用户文件,LR 会在第 11 轮迭代开始循环使用 u1001 的数据,订单号就会冲突。因此参数文件行数最好大于用户数,否则就得在测试环境里允许重复下单。
6.2 脚本回放率与事务成功率的双重验证
脚本可以回放不代表压测结果可信——这是我在某个图像处理 Demo 的压测里学到的最深刻的一课。当时脚本回放成功率 100%,但压测报告里事务成功率只有 40%,原因是脚本虽然发出请求了,但业务逻辑并没有真正跑通(比如下单流程因为库存不足而失败,但 HTTP 层面返回仍然是 200)。
从那以后我每次压测前都强制走一遍「双率验证」:先在单用户回放时检查响应体里的业务状态码(不是 HTTP 状态码),确认 Error Code 为成功;再用 10 并发的小场景压 5 分钟,观测事务成功率是否稳定在 95% 以上;全部通过后才进入正式压测。现在的 LR11 脚本里我会在事务块后插入校验逻辑:
lr_start_transaction("下单事务"); web_reg_save_param("resp_code", "LB=\"code\":\"", "RB=\"", "Search=Body", LAST); web_url("create_order", "URL=http://api.test.internal/create_order", LAST); if (strcmp(lr_eval_string("{resp_code}"), "0") == 0) { lr_end_transaction("下单事务", LR_PASS); } else { lr_end_transaction("下单事务", LR_FAIL); }这段脚本是给事务判定装的「照妖镜」——只有业务响应码为 0 的事务才算通过,HTTP 200 但业务失败的事务会被如实标记为失败。压测执行过程中我还会打开 Controller 的 Online Monitor,实时盯着事务成功率的曲线,一旦跌到阈值以下就立即调低并发数,而不是等压测结束再去翻报告。
这套「LR12 录制 + LR11 压测」的组合方案是我在资源有限的项目里最常用的一条捷径,它绕过了 LR12 商业许可的高昂价格,也避开了 LR11 无法录制移动端脚本的硬伤。唯一的代价是两次脚本微调:一次是清洗录制产物里的第三方请求,另一次是处理 LR11 不兼容的新函数。只要把这些步骤按上面说的顺序走通,再用参数化和事务校验把脚本加固一遍,后端服务在 2W 并发以下的表现基本都能摸到底。希望帮到你。
本文还有配套的精品资源,点击获取