你笑了

你的笑,是星星跳跃浪花的笑

0%

JMeter 安装配置

JMeter

一个开源的负载测试工具,可以用于测试静态和动态资源,确定服务器的性能和稳定性

下载

地址:https://jmeter.apache.org/download_jmeter.cgi

安装

需要安装 JDK8

1
2
3
4
$ java -version
openjdk version "1.8.0_392"
OpenJDK Runtime Environment (build 1.8.0_392-8u392-ga-1~20.04-b08)
OpenJDK 64-Bit Server VM (build 25.392-b08, mixed mode)

将下载的 JMeter 压缩包解压到指定目录后,执行 bin 目录下的 jmeter.sh 即可启动

windows 双击jmeter.bat

配置环境变量

  • 在.bashrc 中添加

    1
    export PATH=$HOME/opt/apache-jmeter/bin:$PATH
  • 应用

    1
    source .bashrc

使用

切换中文

Options -> Choose Language -> Chinese (Simplified)

安装插件

  1. 下载Plugins Manager插件,放到 jmeter目录的 /lib/ext 下面,重启

  2. 重启后在选项菜单中有一个 Plugins Manager 选项

  3. 在 Avaliable Plugins 选项下搜索并安装

3 Basic Graphs

显示 TPS 的实时折线图

5 Additional Graphs

显示吞吐量,连接时间等

PerfMon(Servers Performance Monitoring)

监控CPU、内存、磁盘IO、网络IO

需配合 PerfMon Server Agent 使用,但是很久没更新

各种组件

JMeter 的组件有线程组、取样器、配置元件、前置处理器、后置处理器、定时器、断言、逻辑控制器、监听器。

  • 取样器:生成各种协议的请求,主要用于编辑用户请求时的传参数据。
  • 配置元件:辅助请求,简化请求数据编辑的内容。
  • 线程组:管理请求的运行时间和数量的限制。进行性能测试时必须设置。
  • 前置处理器:请求之前的数据管理。
  • 后置处理器:响应之后的数据管理。
  • 断言:针对请求后的响应内容做预期结果的判断。
  • 逻辑控制器:控制各种请求或元件的运行顺序和规则。
  • 监听器:对最后结果进行展示,可以图形展示,也可以数据形式进行展示。
  • 定时器:控制请求的运行时间。

JMeter 的组件其作用域,例如在线程组下添加的配置元件会针对整个线程组中所有的请求,在某个请求下添加的配置元件仅针对该请求

定义变量

用户定义的变量

  • 添加测试服务器的 host 和 port 等信息

CSV 数据文件设置

从CSV文件中读取参数,构造动态变化的业务请求

CSV格式

1
2
3
4
id,name
1,ali
2,pts
3,jmeter

配置

  • 如果添加了表头,则需要将忽略首行设置为true

函数变量

内置变量

vars

线程组 局部变量,只能在同一线程组内传递数据

通常用于在测试执行期间动态生成值,例如从响应中提取数据并将其存储在变量中供后续请求使用。

通过如下方式设置和访问:

  • 在非 beanshell 环境里使用 ${varName} 语法访问变量的值。
  • 在 beanshell 环境里使用 vars.get("varName") 语法访问变量的值,vars.put("varName", "value") 语法设置变量的值。
props

JMeter 全局变量,可以跨线程组传递数据

通常用于在测试执行期间传递数据

通过如下方式设置和访问:

  • 在非 beanshell 环境里使用${__P(propName)} 语法访问变量的值。
  • 在 beanshell 环境里使用 props.get("propName") 语法访问变量的值, props.put("propName", "value") 语法设置变量的值。

引用变量

通过${variable} 引用

如果是字符串格式,则用双引号包裹,不影响解析

函数

通过函数动态生成一些请求参数

time

动态生成13位时间戳

digest

动态生成摘要

uuid

返回一个 uuid v4 版本的随机id

引用方式:

1
${__UUID()}

JSON Path

由一系列的属性名和数组索引组成:以 “$.” 开头,用“.”和“[]”分隔

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"name": "John",
"age": 30,
"cars": [
{
"name": "Ford",
"models": [
"Fiesta",
"Focus",
"Mustang"
]
},
{
"name": "BMW",
"models": [
"320",
"X3",
"X5"
]
}
]
}
  • $.name:获取 “John”
  • $.cars[0].name:获取 “Ford”
  • $.cars[1].models[2]:获取 “X5”

Bean Shell

一种完全符合 Java 语法规范的脚本语言。允许用户在 JMeter 中编写自定义脚本

JMeter 中很多地方都可以使用 BeanShell 脚本,如:采样器(BeanShell Sampler),前置处理器(BeanShell PreProcessor),后置处理器(BeanShell PostProcessor),断言(BeanShell Assertion),定时器(BeanShell Timer),监听器(BeanShell Listener)。使用 BeanShell 脚本可以很容易地扩展 JMeter 的功能

  • 在测试计划中使用复杂的逻辑控制。
  • 动态地生成HTTP请求参数。
  • 在测试过程中处理响应数据。
  • 自定义结果分析器。

常用内置对象

log

记录日志。Jmeter 用 log4j 记录日志,打印的日志会记录到bin/jmeter.log文件。输出信息和错误的API 分别是 log.info``()log.error()

多个字符串需要用+ 拼接

1
log.info("a"+vars.get("token"))
vars

操作 JMeter 变量。可以在 HTTP 请求等地方用到

Jmeter 变量是在线程启动时,拷贝到线程的,类似线程的局部变量。所以一个线程更新了变量,不会影响到另一个线程。

获取变量:

1
vars.get("name")

设置变量。如果变量不存在会创建:

1
vars.put("key", "value")
props

操作 JMeter 的配置文件:jmeter.properties。

获取配置的值:

1
props.get("key")

设置配置的值:

1
props.put("key", value)
data

当前请求的响应数据,可以用String str = new String(data, “utf-8”)转成字符串再打印出来。类型是byte[],即字节数组。

示例

https://apifox.com/apiskills/jmeter-beanshell/

生成随机数,并设置到 JMeter 变量上

1
2
3
4
5
import java.util.Random;

Random rand = new Random();
int num = rand.nextInt(100);
vars.put("randomNumber", String.valueOf(num));

计算两个变量的和

1
2
3
4
int num1 = Integer.parseInt(vars.get("num1"));
int num2 = Integer.parseInt(vars.get("num2"));
int sum = num1 + num2;
vars.put("sum", String.valueOf(sum));

构造 HTTP 请求参数

1
2
3
4
String param1 = URLEncoder.encode(vars.get("param1"), "UTF-8");
String param2 = URLEncoder.encode(vars.get("param2"), "UTF-8");
String params = "param1=" + param1 + "&param2=" + param2;
vars.put("params", params);

获取 HTTP 响应头中的某个值

1
2
3
4
5
6
7
8
9
10
11
12
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

String url = vars.get("url");
DefaultHttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);
Header header = response.getFirstHeader("Content-Type");
String contentType = header.getValue();
vars.put("contentType", contentType);

执行 HTTP 请求并解析响应数据

1
2
3
4
5
6
7
8
import org.apache.commons.io.IOUtils;
import java.net.URL;
import java.nio.charset.StandardCharsets;

String url = vars.get("url");
String response = IOUtils.toString(new URL(url), StandardCharsets.UTF_8);
// 这边可以放解析响应的逻辑
vars.put("response", response);

发送电子邮件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;

String host = vars.get("host");
String port = vars.get("port");
String username = vars.get("username");
String password = vars.get("password");
String from = vars.get("from");
String to = vars.get("to");
String subject = vars.get("subject");
String body = vars.get("body");

Properties props = new Properties();
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", port);
props.put("mail.smtp.auth", "true");
Session session = Session.getInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
message.setSubject(subject);
message.setText(body);
Transport.send(message);

概念

RT

response time 响应时间

请求从开始到收到响应花费的时间

Transaction

一个完整的请求-响应流程,即一个客户机向服务器发送请求然后服务器做出响应的过程

VU

virtual user 虚拟用户数(并发用户),即JMeter 中的一个线程

  • 注册用户一般指数据库中存在的用户
  • 在线用户只是”挂”在系统上,对服务器不产生压力
  • 并发用户会对服务器产生压力

TPS

Transactions per Seconds

单位时间内完成的事务个数,是衡量系统性能的一个非常重要的指标

请求总数/总时长

线程总数/启动时间

线程总数由CPU型号决定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ lscpu
架构: x86_64
CPU 运行模式: 32-bit, 64-bit
字节序: Little Endian
Address sizes: 39 bits physical, 48 bits virtual
CPU: 12 # 该处理器可以并行处理的线程总数为 12
在线 CPU 列表: 0-11 # 系统识别到的 CPU 核心编号
每个核的线程数: 2 # 每个核心支持 2 个线程
每个座的核数: 6 # 这是一个六核心处理器
座: 1 # 这台机器上安装了一个 CPU
NUMA 节点: 1
厂商 ID: GenuineIntel
CPU 系列: 6
型号: 151
型号名称: 12th Gen Intel(R) Core(TM) i5-12400

性能评价

  • 系统的性能由TPS决定,跟并发用户数没有多大关系
  • 一般情况下,大型系统(业务量大、机器多)做压力测试,10000~50000个用户并发,中小型系统做压力测试,5000个用户并发比较常见

测试指标

一般分为业务指标、资源指标、应用指标、前端指标。

  • 业务指标:如并发用户数、TPS(系统每秒处理事务数)、成功率、RT。
  • 资源指标:如CPU资源利用率、内存利用率、I/O、内核参数(信号量、打开文件数)等。
  • 应用指标:如空闲线程数、数据库连接数、GC/FULL GC次数、函数耗时等。
  • 前端指标:如页面加载时间、网络时间(DNS、连接时间、传输时间等)