---
order: 4
---
# 使用JMeter压力测试

压力测试的目的是通过执行可重复的负载测试，了解系统可靠性、性能瓶颈等，以提高软件系统的可靠性、稳定性，减少系统的宕机时间和因此带来的损失，我们推荐使用JMeter对SuccBI进行压力测试。

本文将以服饰数据分析项目测试过程为例，介绍如何使用JMeter对SuccBI进行压力测试。

压力测试主要步骤为：

\[\[toc]]

## 测试前准备{#pre-test}

压力测试的实现方式是模拟实际环境中用户对BI系统的操作，测试脚本会尽量对其进行还原，所以需要提供测试的详细步骤，使测试脚本尽可能准确，避免系统上线后的实际表现与测试结果不符。因此测试前需要提供以下信息：

### 材料准备{#information-prepared}

1. 环境地址
2. 服务器配置：CPU核心数量，内存大小，磁盘空间，系统版本等信息
3. web服务器和数据库服务器的用户名密码
4. 预计并发量及理想的响应时间：根据用户总量，操作场景及项目要求估算
5. 测试用户：确认测试用户数量大于等于并发量且权限正确

### 测试对象{#object}

测试对象一般是用户最常查看操作的页面，例如服饰数据分析项目中根据用户的查看频率，确认测试对象为首页看板、总体销售情况、分区销售情况、全国销售情况、月销汇总表、销售明细表

### 测试场景{#scene}

实际使用中，有多少用户同时登录，每个用户登录以后做什么操作，这样的场景会持续多长时间。例如：服饰数据分析项目发布后，总用户有200人，同时在线人数最大为50人，每个用户登录后会先查看`首页看板`仪表板，再在测试对象中随机浏览2个数据模型或报表，并导出数据，操作完成后用户注销登录

### 测试方法{#project}

测试过程中为了探测系统的瓶颈，一般会采用梯度施压的方式进行并发测试，例如服饰数据分析项目测试中按照`最大在线人数`的25%、50%、75%、100%、125%、150%进行并发测试，即并发量分别为：10、25、40、50、65、80，测试循环时间为3分钟。

### 修改系统配置{#modify-configuration}

确定本次测试的最高并发量后，需要将数据库最大连接数、系统数据源连接[最大连接数](../../data-connect/datasources.md#properties-setting)都修改为2倍最高并发量大小

以上准备工作都确认完成后，就可以开始根据模板完善测试脚本了。

## 导入模板并补充测试全局设置{#import-template}

1. 点击[此处](https://www.jianguoyun.com/p/DRv-MC8Qz--gChiqod0EIAA)(提取码：SuccBI)下载模板，在`菜单栏-文件`中打开下载的`jmeter-template-succbi.jmx`
   ![导入模板](./images/2020-09-22-16-18-03.png)
2. 点击[HTTP请求默认值](./jmeter.md#HTTP请求默认值)组件，按照目标测试环境实际情况补充`协议`、`服务器名称或IP`、`端口号`信息，例如测试环境地址为`http://192.168.3.51:8080`，则分别填入`http`、`192.168.3.51`、`8080`
   ![补充HTTP请求默认值](./images/2020-09-22-11-33-42.png)
3. 点击[CSV数据文件设置](./jmeter.md#CSV数据文件设置)组件，按照实际测试需求，补充`文件名`，即外部存储了测试用户名/密码的csv文件，由于模板中已经定义了用户名/密码变量，因此请确保csv的列头分别为**user/password**
   ![补充CSV数据文件设置](./images/2020-09-22-11-46-30.png)
4. 点击`线程组`组件，按照实际测试需求补充`线程数`、`Ramp-Up时间`、`循环数`，其中线程数/Ramp-Up时间即为点击率，例如线程数为100，Ramp-Up时间为10，则点击率为10次/秒；若需要进行无限循环的定时测试，可勾选`调度器`后，填写`持续时间`
   ![补充线程组](./images/2020-09-23-11-11-27.png)

至此，测试脚本的全局设置就全部完成了。

## 按照测试场景录制请求{#record-request}

在[JMeter工具](./jmeter.md#subject)中已经介绍了如何使用`非测试元件-HTTP代理服务器`来录制HTTP请求，但录制的请求比较分散，我们需要根据操作事务将其分类，处理方法如下：

1. 将所有被缓存的请求移动到`资源下载`事务控制器中，缓存情况可通过浏览器开发者工具-NETWOKR查看
   ![NETWORK](./images/2020-09-23-11-48-49.png)

2. 将本次事务的主要负载请求移动到`操作名称`事务控制器中，并将**HTTP请求** > **路径** 中的`rcuuid`值修改为JMeter内置的`${__UUID}`函数(若不存在rcuuid属性则不需要处理)，以访问`首页看板`为例，对服务器产生负载的操作主要为`查询数据`，对应的请求为`querydata`，则将所有`querydata`请求移动到`数据查询`事务控制器中，请求名称修改为"数据查询+编号"的形式，并将**HTTP请求** > **路径** 中的`rcuuid`值修改为`${__UUID}`
   ![querydata](./images/2020-09-23-11-51-24.png)

   ::: details 点击查看操作请求对照
   | 负载操作 | 对应请求名称 |
   | :---: |:---:|
   | 查询数据 | querydata |
   | 导出数据库表数据 | exportdata |
   | 模型工具栏导出数据 | exportdata |
   | 上传文件数据源 | uploadDataFile |
   | 导出元数据 | export |
   | 导入元数据 | import |
   | 导出pdf | exportPdf |
   :::

3. 将其他请求移动到`其他`事务控制器中

处理完成的整个`访问首页看板`事务如下：
![访问首页看板事务](./images/2020-09-23-13-57-47.png)

::: tip 提示
当测试多个对象时，在线程组中添加`事务控制器`时会默认添加到最底部，请按照测试场景的事务顺序将`事务控制器`排序，确保请求的执行顺序是正确的，避免出现先注销再查询的情况
:::

## 增加监听器{#add-monitor}

为了记录脚本中的请求执行结果，还需要在测试计划中添加`监听器`组件，模板中已经添加了[聚合报告](./jmeter.md#聚合报告)、[查看结果树](./jmeter.md#查看结果树)，若需要在测试过程中对服务器硬件状态进行监控，请配置[服务器性能监控](./jmeter.md#服务器性能监控)。

至此，整个测试脚本就完成了。

## 调试脚本{#debug}

脚本完成后，还需要进行调试来验证脚本的可用性。将`线程数`调低（10以下），点击工具栏中的`启动`，查看监听器中请求的返回结果是否正确，反复调试直到结果符合预期。
:::warning
由于GUI模式下界面会消耗很多系统资源，并且测试过程中产生的结果日志是保存在Jmeter的运行内存中，长时间运行会导致测试机卡顿，影响施压，Jmeter官方也强调，只在GUI模式下调试脚本！因此不要直接调高`线程数`施压，而是要在调试确认脚本可用后，在Linux服务器中运行测试脚本。
:::
![启动](./images/2020-09-23-14-15-26.png)

## 运行脚本{#start}

脚本调试完成后，按照[测试方法](#project)中设定的并发量，修改`线程数`，保存后将生成的jmx文件移动到Linux服务器磁盘中，运行如下命令开始压力测试

```sh
/path/to/JMeter/bin/jmeter -n -t test.jmx -l /path/to/logs/log.jtl -e -o /path/to/report
```

**参数详解**

- -n：非GUI模式
- -t：指定要运行的JMeter测试脚本
- -l：记录结果的文件，每次运行之前要确保之前没有运行过，即xx.jtl不存在，否则会报错
- -e：在脚本运行结束后生成html报告
- -o：用于存放html报告的目录（目录要为空，否则报错）

测试脚本运行完成后，导出-o参数定义的整个目录，打开其中的`index.html`，查看本次测试结果的简易报告；也可将log.jtl文件导出，并在GUI端的[监听器](#add-monitor)中打开，即可展示对应的监听结果。

## 结果分析{#analyse-result}

脚本运行完成后，就需要对测试结果进行分析，分析对象主要为[聚合报告](./jmeter.md#聚合报告)与[服务器性能监控](./jmeter.md#服务器性能监控)

**聚合报告重点指标：**

- 样本、吞吐量：反映系统处理请求速度的指标，如果太小则可能是发生了阻塞
- 平均值：请求的平均响应时间
- 90%百分位、95%百分位：响应时间的主要指标，反映实际情况下绝大多数用户的响应等待
- 最大值：最大值过大则可能是发生了阻塞
- 异常%：正常情况下不应有异常，若存在异常则需要在[查看结果树](./jmeter.md#查看结果树)中获取异常信息，并反馈给研发同事

**服务器性能监控**则主要关注在各并发量下，服务器资源的占用是否合理

例如服饰数据分析项目在80并发下的聚合报告与服务器硬件占用情况如图

![80聚合报告](./images/2020-09-23-16-41-07.png)
![80服务器占用](./images/2020-09-23-17-04-25.png)

聚合报告中指标均表现良好，服务器性能还存在余量，服务器目前配置能够负载系统80并发量的压力

至此，使用JMeter的压力测试就完成了，还需要将测试过程和结果归纳为测试报告，可点击[这里](https://www.jianguoyun.com/p/DWQSdTAQ3O-gChjA7qwE)下载服饰行业数据分析测试报告，以此为模板编写自己的压力测试报告。

## 问题排查{#check-issues}

### 出现异常"@default连接池已满"

请确认数据库最大连接数、系统数据源连接最大连接数是否都设置为2倍最高并发量大小

### 资源下载请求异常

- **并发量少时**：确认网络是否瓶颈，例如带宽被限制、不在同一局域网等情况，当资源下载过多时，网络瓶颈会导致请求超时出现异常
- **并发量多时**：若并发量较少时未出现异常，当并发数量增多后才有部分异常出现，则可能是JMeter本身[内存配置](./jmeter.md#config)的较低，需要根据测试端内存情况进行相应调高

### 其他请求异常

1. 确认`事务控制器`的排列顺序与测试场景一致，若将注销请求排列在其他请求之前，会导致后续请求结果出现无权限的异常。
2. 请确认是否将请求路径中的`rcuuid`值修改为`${__UUID}`：querydata等长任务依赖请求路径中的`rcuuid`来判断是否重复执行，因此需要将该值定义为JMeter中的`${__UUID}`函数，保证每次发起的请求都会被执行。
