浅谈取样器之HTTP请求
HTTP请求(HTTP Request) 是进行Web应用负载测试时最常用的取样器类型,允许用户模拟各种HTTP请求,如GET、POST等,以评估服务器在不同负载条件下的表现。
添加HTTP请求
- 线程组:在刚创建的线程组上右键 > “添加(Add)” > “取样器(Sampler)” > “HTTP请求(HTTP Request)”。
- 配置HTTP请求:
○ 名称(Name):为取样器提供一个有意义的名称,便于识别。
○ 注释(Comments):可选,用于记录测试目的或额外信息。
○ 协议(Protocol):选择HTTP或HTTPS。
○ 服务器名称或IP(Server Name or IP):输入目标服务器的域名或IP地址。
○ 端口(Port):默认情况下,HTTP为80,HTTPS为443,可根据实际情况调整。
○ 协议(Protocol):选择HTTP或HTTPS。
○ 方法(Method):请求方法,如GET、POST、PUT等。
○ 路径(Path):目标URL的路径部分,不包括服务器地址和端口。
○ 内容编码(Content Encoding):如UTF-8,根据服务器需求设置。
○ 自动重定向(Automatic Redirection):只针对Get和Head请求,自动重定向到最终目标页面,但Jmeter不记录重定向的中间过程,只记录最终返回结果。在察看结果树中,只能看到的服务器返回
○ 跟随重定向:当响应是3XX时,自动跳转到目标地址。Jmeter记录中间过程。在察看结果树中,可看到所有请求从服务器返回
○ 使用KeepAlive:使用保活
○ 对Post使用multipart/form-data:表单方式提交
○ 浏览器兼容:当勾选multipart/form-data时,勾选此项会截掉http请求头中的Content-Type和Content-Transfer-Encoding,而只发送Content-Disposition部分。
○ 参数(Parameter):在请求中发送带参数的URL ,JMeter提供了一个简单的对参数化的方法。用户可以将URL中所有参数设置在本表中,表中的每一行是一个参数值对(对应RUL中的 名称1=值1)。编码这个选项最好勾选,因为如果参数值内含有ASCII Control Chars或者Non-ASCII characters或者其他符号的话,如果不勾选会导致发送失败(乱码问题),勾选的话会自动将含有的这些特殊符号进行编码
○ 消息体数据(Body Data):通请求一起发送的数据消息,这里可以支持多种数据格式 json、xml等。
○ 文件上传(File Upload):在请求中发送文件。通常HTTP文件上传行为可以通过这种方式模拟,参数名称就是发送文件对应的参数,MINE Type为资源媒体类型。。
高级配置
该部分内容摘自,内容已经比较全面:
HTTP高级设置说明
客户端实现(Client implementation)
● 实现( Implementation):发送http请求的方式。可选项为Java和HttpClient4,默认为HttpClient4。
HttpClient4是Java工具包实现的请求方式,是基于.net工具包二次定制,效率高。
如果是上传文件的话一定要选择,否则请求发送成功了,其实文件并未上传成功。
● 超时(毫秒)<Timeouts(milliseconds)>:超时设置。
链接(Connect):连接超时时间,单位为毫秒;
响应(Response):响应等待超时时间,单位为毫秒;
从HTML文件嵌入资源(Embedded Resources from HTML Files)
● 从HTML文件获取所有内含的资源(Retrieve All Embedded Resources):
当该选项被选中时,JMeter在发出HTTP请求并获得响应的HTML文件内容后,还对该HTML进行解析,并获取HTML中包含的所有资源(图片、flash等),默认不选中。
如果用户只希望获取页面中的特定资源,可以在后边的URLs must match文本框中,填入需要下载的特定资源表达式,这样只有能匹配指定正则表达式的URL指向资源会被下载。
● 并行下载(Parallel downloads):是否使用自设资源池,勾选后可设置大小。
● 数量(Number):资源池大小,默认设置为6。
● 网址必须匹配(URLs must match):URL匹配过滤,填写此项则只会下载与此内容项匹配的url的资源。
源地址
只用于http协议且Implementation为HttpClient4的情况,此属性用于启用IP欺骗,会重写了这个http请求使用的默认本地IP地址。
用于JMeter主机具有多个IP地址的情况。该值可以是主机名、IP地址或网络接口设备,如“ey0”或“l0”或“wlan0”。
可以设置多个,防止IP地址被服务端拉黑。
IP/主机名(IP/Hostname):使用特定的IP地址或(本地)主机名。
设备(Device):选择该接口的第一个可用地址,该设备可以是IPv4或IPv6。
设备IPV4:选择名称设备的IPv4地址。
设备IPV6:选择名称设备的IPv6地址。
代理服务器
不想用本机的地址来发送Http请求,而想使用代理服务器时则填写。
服务器名称或IP:代理服务器的名称或者IP地址。
端口号:该代理的端口号。
用户名:使用该代理的用户名。
密码:用户密码。
保存响应为MD5哈希
选中该项,在执行时仅记录服务端响应数据的MD5值,而不记录完整的响应数据。在需要进行数据量非常大的测试时,建议选中该选项,以减少取样器记录响应数据的开销。
到这里“HTTP请求”这个取样器介绍完了,每个取样器的页面和用法都不用,这里不能一一进行说明,以后再用到哪种取样器(Samplers)会单独讲解。
应用实例
情况1:自动重定向和跟随重定向
使用SpingBoot框架编写如下测试脚本
@GetMapping(value = "/welcome")
public String welcome(){
try{
Random random = new Random();
int randomNumber = random.nextInt(1000);
Thread.sleep(randomNumber);
}
catch (Exception e){
e.printStackTrace();
}
return "{\"total\":2,\"data\":[{\"id\":123,\"name\":\"John Doe\",\"email\":\"johndoe@example.com\",\"phone\":\"123-456-7890\",\"address\":{\"street\":\"123 Main St\",\"city\":\"New York\",\"state\":\"NY\",\"zip\":\"10001\"},\"interests\":[\"sports\",\"music\",\"travel\"]},{\"id\":456,\"name\":\"Jane Smith\",\"email\":\"janesmith@example.com\",\"phone\":\"987-654-3210\",\"address\":{\"street\":\"456 Elm St\",\"city\":\"Los Angeles\",\"state\":\"CA\",\"zip\":\"90001\"},\"interests\":[\"reading\",\"cooking\",\"hiking\"]}]}";
}
@GetMapping("/getinfo")
public RedirectView redirectAndRequest(RedirectAttributes attributes) {
// 重定向到目标URL
RedirectView redirectView = new RedirectView();
redirectView.setUrl("http://127.0.0.1:8091/request");
return redirectView;
}
@GetMapping("/request")
@ResponseBody
public String handleRequest() {
ModelAndView modelAndView = new ModelAndView("redirect:/api/redirect");
// 发起请求到目标URL
RestTemplate restTemplate = new RestTemplate();
return restTemplate.getForObject("http://127.0.0.1:8091/welcome", String.class);
}
我们编写如下测试脚本
线程组:保持默认
HTTP请求:协议http,服务器名称或IP为127.0.0.1,端口号为8091,方法为GET,路径为/getinfo,内容编码为utf-8
跟随重定向
勾选跟随重定向,执行脚本,查看结果树
并且可以查看HTTP请求-0时,取样器结果
Thread Name: 线程组 1-1
Sample Start: 2024-07-26 15:42:46 CST
Load time: 3
Connect Time: 2
Latency: 3
Size in bytes: 187
Sent bytes:125
Headers size in bytes: 187
Body size in bytes: 0
Sample Count: 1
Error Count: 0
Data type (“text”|“bin”|“”):
Response code: 302
Response message:
当响应是3XX时,自动跳转到目标地址。Jmeter记录中间过程。在察看结果树中,可看到所有请求从服务器返回
自动重定向
勾选自动重定向,执行脚本,查看结果树
Jmeter不记录重定向的中间过程,只记录最终返回结果。在察看结果树中,只能看到的服务器返回
情况2:使用KeepAlive
勾选使用KeepAlive
勾选使用KeepAlive,执行脚本,查看结果树中HTTP请求中请求的Request Headers,结果如下
Connection: keep-alive
Host: 127.0.0.1:8091
User-Agent: Apache-HttpClient/4.5.7 (Java/1.8.0_101)
不勾选使用KeepAlive
不勾选使用KeepAlive,执行脚本,查看结果树中HTTP请求中请求的Request Headers,结果如下
Connection: close
Host: 127.0.0.1:8091
User-Agent: Apache-HttpClient/4.5.7 (Java/1.8.0_101)
情况3:对post使用multipart/form-data
使用SpingBoot框架编写如下测试脚本
@PostMapping(value = "/submitForm")
public String submitForm2(
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "email", required = false) String email) {
return "Received form submission:\nName: " + name + "\nEmail: " + email;
}
我们编写如下测试脚本
线程组:保持默认
HTTP请求:协议http,服务器名称或IP为127.0.0.1,端口号为8091,方法为POST,路径为/submitForm,内容编码为utf-8,参数中添加两个参数,第一个参数名称为name,值为sam,第二个参数名称为email,值为sam@test.com
不勾选使用multipart/form-data
执行脚本,查看结果树中HTTP请求中请求的Request Body,结果如下
POST http://127.0.0.1:8092/submitForm
POST data:
name=sam&email=sam%40test.mail
勾选使用multipart/form-data
执行脚本,查看结果树中HTTP请求中请求的Request Body,结果如下
POST http://127.0.0.1:8092/submitForm
POST data:
–JCZ1_jEfNG9v8Fzfk7tPC0QxSoTxKS8Fy0WwLM
Content-Disposition: form-data; name=“name”
Content-Type: test/plain; charset=UTF-8
Content-Transfer-Encoding: 8bitsam
–JCZ1_jEfNG9v8Fzfk7tPC0QxSoTxKS8Fy0WwLM
Content-Disposition: form-data; name=“email”
Content-Type: test/plain; charset=UTF-8
Content-Transfer-Encoding: 8bitsam@test.com
–JCZ1_jEfNG9v8Fzfk7tPC0QxSoTxKS8Fy0WwLM–
情况4:文件上传
使用SpingBoot框架编写如下测试脚本
@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) {
try {
// 获取上传文件的输入流
InputStream inputStream = file.getInputStream();
// 使用 InputStreamReader 包装输入流,并指定字符编码(根据实际情况选择适当的编码)
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
// 使用 BufferedReader 包装 InputStreamReader,以便逐行读取文件内容
BufferedReader reader = new BufferedReader(inputStreamReader);
// 逐行读取文件内容
String line;
StringBuilder content = new StringBuilder();
while((line = reader.readLine()) != null) {
content.append(line);
}
// 关闭流
reader.close();
inputStreamReader.close();
inputStream.close();
// 打印文件内容(也可以根据需要进行其他操作)
System.out.println("File content: " + content.toString());
return content.toString();
} catch (IOException e) {
e.printStackTrace();
return "Error occurred while uploading file.";
}
}
我们编写如下测试脚本
线程组:保持默认
HTTP请求:协议http,服务器名称或IP为127.0.0.1,端口号为8091,方法为POST,路径为/upload,内容编码为utf-8,勾选对post使用multipart/form-data,文件上传中文件名称添加文件路径:D:\test.txt,参数类型为file,MIME类型为multipart/form-data,其中test.txt中的文件内容为test upload。
执行脚本,查看HTTP请求中响应数据中的Response Body内容,结果展示为:test upload。
情况5:高级中设置保存响应为MD5哈希
在情况4的基础上,HTTP请求中的高级中将其他任务中勾选保存响应为MD5哈希
执行脚本,查看HTTP请求中响应数据中的Response Body内容,结果展示为:7669d00ad7a4c66040f036d771241716
分析结果
测试完成后,通过查看“查看结果树(View Results Tree)”、“聚合报告(Aggregate Report)”等监听器来分析响应时间、吞吐量等性能指标。
总结
HTTP请求取样器是JMeter中进行Web应用性能测试的核心组件,通过灵活配置,可以模拟复杂的用户行为和高负载场景,帮助开发者和测试工程师发现并优化系统瓶颈,提升应用性能。掌握其使用方法是进行有效性能测试的关键。