1. 摘要
本文讲解如何使用JMeter实现前后端接口的性能测试。JMeter入门实践可参考《【NGINX入门】16.使用JMeter压力测试工具测试NGINX限流配置实践》 《【Jmeter入门】1.JMeter界面及监听器介绍》。
2. 实践内容
2.1 接口请求实例
1. HTTP get与post请求参数传递方法
(1)get请求是普通的键值对
只要用&链接符把他们一个个都放到URL里面就可以了,如下(截图是POST请求点错了,应该是get)
(2) get请求的入参是json格式的
名称 | 说明 |
---|---|
摘要: | 利用httpClient调用接口,成功返回信息 |
接口地址: | (RESTFUL方式) http://192.168.100.87:10051/ngcctcontrol/ws/interfaces/userSatisfy |
请求方式: | GET |
步骤: | 1、利用httpClient模拟接口调用正常情况。 输入报文: { "params":{ "beginTime":"2017-01-01 00:00:00", "endTime":"2017-01-25 00:00:00", "userSatisfy":"1", "userSatisfy2":"1", "serviceTypeId":"otck" }, "object":[], "beans":[]} |
下图是用http请求子节点的前置请求器BeanShell处理json字符串
下图是BeanShell具体内容:json字符串使用在线校验通过后,压缩转义,然后import jdk的方法:
(3)json格式的post请求
只要把入参放到BodyData里面就可以了,记得要先用json在线校验工具进行校验,另外要加http头管理器,在里面加上content-type:Application/json.
2. “用户定义的变量” 的应用
以获取学生信息接口(stu_info) 为例,添加一个“用户定义的变量”,设置变量"host" 以及值,这样在获取学生信息接口(stu_info)就可以通过"${host}"取得“服务器名称或IP”的值。
登陆接口(login)接口也可以应用“用户定义的变量”的方法,如上图所示,在“用户定义的变量”中添加"username", "password" 变量及对应的值, 应用到登陆接口(login)接口请求中即可。
3. "HTTP Cookie 管理器"的应用
以金币充值接口(gold_add)为例,建立一个HTTP请求改名“金币充值”,选取请求方式POST, 输入对应的host, path以及同请求一起发送的参数和值。
由于此接口有权限验证,需要admin用户才可以做操作,需要添加cookie, 因此需要添加"HTTP Cookie 管理器"以传递Cookie。
添加"HTTP Cookie 管理器" 方法如下图所示, 右键“金币充值” -> “添加” -> “配置元件” -> "HTTP Cookie 管理器"
设置Cookie 的名称(即username 的值),值(即login Response 中的sign 值),域(已在“用户定义的变量”中设置,只需输入变量即可,格式为${host})
最后可以通过“察看结果数”的响应数据查看结果。
4. 建立接口间的关联
以下以登陆接口(login)和金币充值接口(gold_add)为例,在这两个接口间建立关联,让金币充值接口(gold_add)可以实时取得登陆接口(login)的"sign" 值,不必再“HTTP Cookie 管理器”中手动输入最新的sign 值。
从“察看结果树”可以看出,登陆接口(login)的Response 结构为Json格式, sign 在 login_info 里面一层。
4.1 应用"jp@gc - JSON Path Extractor" 来实现
右键“登陆” -> “后置处理器 -> "jp@gc - JSON Path Extractor"
通过“察看结果数”得到Response 的结果后, 将“JSONPath Expression” 输入"$.login_info.sign", 设置变量"sign2", 给金币充值接口(gold_add)用
因此需要在“HTTP Cookie 管理器”中将${username}的值输入${sign2},代替之前手动输入的那一串码。
4.2 右键“登陆” -> “后置处理器 -> "正则表达式提取器"
输入对应的值, "jp@gc - JSON Path Extractor" 中类似,将“引用名称”输入"sign2",以保证和“HTTP Cookie 管理器”的一致。将正则表达式中的式用login 接口返回的 "sign": "cd2b43f1688e472e3a516b5a2c6831e8", 中的一串码用(.*) 替换即可。
各参数的含义参考下表:
参数 | 释义 |
---|---|
引用名称 | 在HTTP等请求中,引用此数据,需要用到的名称 |
正则表达式 | 用于将需要的数据提取出来 |
模板 | 表示使用提取到的第几个值: $-1$:表示取所有值 $0$:表示随机取值 $1$:表示取第1个 $2$:表示取第二个 以此类推:$n$:表示取第n个 |
匹配数字(0代表随机) | 0 代表随机取值,1 代表全部取值 |
缺省值 | 如果正则表达式没有搜找到值,则使用此缺省值 |
5. 设置断言
以“增加学生”接口(add_stu)为例,增加响应断言,以验证添加的数据是否成功。如下图所示设置
通过“察看结果数”可以看到“增加学生” 金币结果为绿色,同时响应数据里的确有断言中的设置的"1000"。
6. “HTTP信息头管理器”的使用
以下图中的“获取所有学生信息” 为例,右键“获取所有学生信息” -> “添加” -> “配置元件” -> "HTTP Cookie 管理器" , 输入对应的名称和值即可。
**注意: ** 这里的值需要输入完整的url, 包括http:// (eg, 输入http://api.test.cn)
7. POST 文件的使用方法
与其他POST请求中添加key-value, json 数据不同的是,这个需要在HTTP 请求中点击“Flies Upload” tab, 点击“添加”, 然后通过“浏览”上传本地的文件。
注意: 参数名称必须为"file"。
8. "CSV Data Set Config" 和 “函数助手对话框”的使用
以增加学生接口(add_stu)为例,在本地创建一个文件,添加name 和sex的值,对脚本设置5个线程或者循环5次,以加入这5个用户。
右键“线程组” -> “添加” -> “配置元件” -> "CSV Data Set Config",如果仅应用于“增加学生”接口的话,可以直接在“增加学生”接口下面创建"CSV Data Set Config"。
根据下图添加对应的,"Variable Names" 输入"name" 和"sex", 以逗号隔开,为避免插入的数据乱码,将file encoding 设置为utf-8。
由于"CSV Data Set Config"中的变量名为name 和sex,因此在“增加学生”接口的"Body Data" 中将值分别替换为${name}, ${sex}。
由于“phone”的唯一性,每次插入一条学生信息时phone 都要求不一样,所以对后面8位用随机函数来实现。
9. 数据库的应用
以下是JMeter 驱动数据库列表:
数据库 | 驱动 | 数据库url |
---|---|---|
mysql | com.mysql.jdbc.Driver | jdbc:mysql://host:port/{dbname}?allowMultiQueries=true |
oracle | org.postgresql.Driver | jdbc:postgresql:{dbname} |
PostgreSQL | oracle.jdbc.driver.OracleDriver | jdbc:oracle:thin:user/pass@//host:port/service |
MSSQL | com.microsoft.sqlserver.jdbc.SQLServerDriver或者net.sourceforge.jtds.jdbc.Driver | jdbc:sqlserver://IP:1433;databaseName=DBname或者jdbc:jtds:sqlserver://localhost:1433/"+"library" |
以下以mysql 数据库为例。
添加一个"JDBC Connection Configuration", 根据上表中对mysql的要求设置下图的值。
添加一个"JDBC Request", 由于在Query 中有insert 和select, 所以Query Type 需要选择"Callable Statement", 如果是单个的select 或者insert,可以选取对应的Select Statement 和Update Statement。
通过察看结果数看到"JDBC Request" 请求成功,响应数据里返回insert 和select 的结果。
登陆mysql 数据库,查询发现和Jmeter 中通过察看结果数看到的结果一致。
****注意点:修改Jmeter 中的中文乱码要将"\bin" 路径下的"jmeter.properties" 文件中设置为 "sampleresult.default.encoding=utf-8",如下所示。**
对于Jmeter 里中文显示不出来的问题,可以打开"\bin" 路径下的"jmeter.properties" 文件,如下图所示,将这几个JS开头的注释去掉。
对于以上两个问题,修改后,需将Jmeter 重启才能起效。
10. 虚拟多IP
(1) http的IP地址介绍
X-Forwarded-For 是一个 HTTP 扩展头部。HTTP/1.1(RFC 2616)协议并没有对它的定义,它最开始是由 Squid 这个缓存代理软件引入,用来表示 HTTP 请求端真实 IP。如今它已经成为事实上的标准,被各大 HTTP 代理、负载均衡等转发服务广泛使用,并被写入 RFC 7239(Forwarded HTTP Extension)标准之中。
X-Forwarded-For 请求头格式非常简单,就这样:
X-Forwarded-For: client, proxy1, proxy2
可以看到,XFF 的内容由「英文逗号 + 空格」隔开的多个部分组成,最开始的是离服务端最远的设备 IP,然后是每一级代理设备的 IP。
如果一个 HTTP 请求到达服务器之前,经过了三个代理 Proxy1、Proxy2、Proxy3,IP 分别为 IP1、IP2、IP3,用户真实 IP 为 IP0,那么按照 XFF 标准,服务端最终会收到以下信息:
X-Forwarded-For: IP0, IP1, IP2
Proxy3 直连服务器,它会给 XFF 追加 IP2,表示它是在帮 Proxy2 转发请求。列表中并没有 IP3,IP3 可以在服务端通过 Remote Address 字段获得。我们知道 HTTP 连接基于 TCP 连接,HTTP 协议中没有 IP 的概念,Remote Address 来自 TCP 连接,表示与服务端建立 TCP 连接的设备 IP,在这个例子里就是 IP3。
Remote Address 无法伪造,因为建立 TCP 连接需要三次握手,如果伪造了源 IP,无法建立 TCP 连接,更不会有后面的 HTTP 请求。不同语言获取 Remote Address 的方式不一样,例如 php 是 $_SERVER["REMOTE_ADDR"],Node.js 是 req.connection.remoteAddress,但原理都一样。
还有一个 X-Real-IP,这又是一个自定义头部字段。X-Real-IP 通常被 HTTP 代理用来表示与它产生 TCP 连接的设备 IP,这个设备可能是其他代理,也可能是真正的请求端。需要注意的是,X-Real-IP 目前并不属于任何标准,代理和 Web 应用之间可以约定用任何自定义头来传递这个信息。
参考:https://www.runoob.com/w3cnote/http-x-forwarded-for.html
IP的方法:
(2)CSV导入方式
1.在局域网内,查询一下,哪些ip是闲置的。 ping 加上ip ,如果访问不到,则说明是闲置的
2.打开网络共享,修改自己的ip,设置为固定IP,打开【高级】,添加你查询出的闲置ip
3.新建一个文本,将你的添加的ip 也写入文本中 .(备注:我的文档中加了两种数据,第一列是我的用户id,第二个是我的电脑ip)
例如;
4.打开jmeter,创建自己的线程,新建csv文件。
文件名:就是刚才你存储ip的文档名称
变量名:随意给他起个你能记住的名字
分隔符:因为我这个一个文档中有两列数据,我的分割符是逗号,你们随意。
5.开始配置ip,找到你的http请求,选择高级,找到ip/主机名 。把你刚才设置的变量加上去
(3)随机生成ip
添加http信息头管理器,
至二级添加线程组,添加http请求就行了。
修改的不是X-localAddress,不确认是否有效,待验证。
本文转载自 用Jmeter进行接口测试