并发模拟工具详解

开发 开发工具
严格来说postMan并不是并发请求,而是串行执行的,现在用postMan更多的是用来测试Http连接的一个工具,但是也是一个很实用的工具,也有一些比较强大的功能和优点

[[380130]]

 简介:

  • 一、Psotman
  • 二、Apache Bench(AB)
  • 三、JMeter
  • 四、代码

一、Psotman:Http请求模拟工具

严格来说postMan并不是并发请求,而是串行执行的,现在用postMan更多的是用来测试Http连接的一个工具,但是也是一个很实用的工具,也有一些比较强大的功能和优点

1.1 下载地址

  1. 1) Postman for MAC:https://app.getpostman.com/app/download/osx64?utm_source=site&utm_medium=apps&utm_campaign=macapp&_ga=2.21151352.2119858274.1527039878-1088353859.1527039878 
  2. 2) Postman for windows X64:https://app.getpostman.com/app/download/win64?_ga=2.201562513.1250696341.1530543681-1582181135.1530543681 
  3. 3) Postman for windows X86:https://app.getpostman.com/app/download/win32?_ga=2.21151352.2119858274.1527039878-1088353859.1527039878 
  4. 4) Postman for linux X64:https://app.getpostman.com/app/download/linux64?_ga=2.96050783.2119858274.1527039878-1088353859.1527039878 
  5. 5) Postman for Linux X86:https://app.getpostman.com/app/download/linux32?_ga=2.96050783.2119858274.1527039878-1088353859.1527039878 
  6. 6) 官网地址:https://www.getpostman.com/ 

1.2 操作说明(以win64为例)

1、打开Postman,输入我们需要测试的网址,点击左边的"+",保存请求


2、点击"+"后,弹出下面提示,保存链接地址生成测试文件夹名称

3、保存成功后,选择"collections"后选择文件夹名为"gbfTest"的,点击小三角——点击Run

 

4、这里我们可以设置请求次数和间隔时间,一般间隔时间会设置为0,设置好之后,我们点击Run gbfTest运行

5、查看结果,从图中我们可以看到百度的响应速度还是很快的


6、点击 Run Summary 可以看到运行结果概述


7、测试全部通过


8、测试结果可以通过点击Export Results按钮进行导出,方便分析每次的请求时间

 

 

二、Apace Bench(AB):Apache附带的工具,测试网站性能

2.1 简介

Apache Bench 是 Apache 服务器自带的一个web压力测试工具,简称ab。ab又是一个命令行工具,对发起负载的本机要求很低,根据ab命令可以创建很多的并发访问线程,模拟多个访问者同时对某一URL地址进行访问,因此可以用来测试目标服务器的负载压力。总的来说ab工具小巧简单,它不仅可以对apache服务器进行网站访问压力测试,也可以对或其它类型的服务器进行压力测试。比如nginx、tomcat、IIS等,上手学习较快,可以提供需要的基本性能指标,但是没有图形化结果,不能监控

2.2 原理

ab命令会创建多个并发访问线程,模拟多个访问者同时对某一URL地址进行访问。它的测试目标是基于URL的,因此,它既可以用来测试apache的负载压力,也可以测试nginx、lighthttp、tomcat、IIS等其它Web服务器的压力

2.3 Apache Bench安装

Apache服务器,下载地址:https://www.apachelounge.com/download/

选择:httpd-2.4.41-win64-VS16 下载目录结构:

2.4 Apache Bench 使用

运行环境:Windows7 Apache Bench版本:httpd-2.4.41-win64-VS16

1、进入cmd目录下,进入我们解压好的Apache Bench目录下


3 使用命令

  1. ab -c 10 -n 10 http://www.baidu.com/ 或者 ab.exe -n 1000 -c 500 http://www.baidu.com 

ab -c 10 -n 10 http://www.baidu.com/ 或者 ab.exe -n 1000 -c 500 http://www.baidu.com

对百度首页进行一个请求总数为1000,本次请求并发数为500的测试


参数分析:

  1. C:\Users\Lenovo\Downloads\httpd-2.4.41-win64-VS16\Apache24\bin>ab.exe -n 1000 -c 
  2.  500 http://www.baidu.com/path 
  3. This is ApacheBench, Version 2.3 <$Revision: 1843412 $> 
  4. Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 
  5. Licensed to The Apache Software Foundation, http://www.apache.org/ 
  6.  
  7. Benchmarking www.baidu.com (be patient) 
  8. Completed 100 requests 
  9. Completed 200 requests 
  10. Completed 300 requests 
  11. Completed 400 requests 
  12. Completed 500 requests 
  13. Completed 600 requests 
  14. Completed 700 requests 
  15. Completed 800 requests 
  16. Completed 900 requests 
  17. Completed 1000 requests 
  18. Finished 1000 requests 
  19.  
  20.  
  21. Server Software:        Apache      #测试服务器的名字 
  22. Server Hostname:        www.baidu.com  #请求的URL主机名 
  23. Server Port:            80        #请求端口 
  24.  
  25. Document Path:          /path      #请求路径   
  26. Document Length:        222 bytes    #页面大小 
  27.  
  28. Concurrency Level:      500        #并发量,设置的参数之一 
  29. Time taken for tests:   45.805 seconds  #整个测试所用的时间/秒 
  30. Complete requests:      1000      #完成的请求数 
  31. Failed requests:        0        #失败的请求数 
  32. Non-2xx responses:      1000      #接收到的HTTP响应数据的头信息中含有2XX以外的状态码,则会在测试结果中显示另一个名为“Non-2xx responses”的统计项,用于统计这部分请求数(1000) 
  33. Total transferred:      484000 bytes  #表示所有请求的响应数据长度总和 
  34. HTML transferred:       222000 bytes  #表示所有请求的响应数据中正文数据的总和 
  35. Requests per second:    21.83 [#/sec] (mean)    #吞吐率,吞吐率是与并发数相关的,使请求总数相同,但如果并发数不一样,吞吐率还是很可能有很大差异的 
  36. Time per request:       22902.310 [ms] (mean)    #用户平均请求等待时间。也就是一次并发总的时间 
  37. Time per request:       45.805 [ms] (mean, across all concurrent requests)    #服务器平均请求等待时间。也就是一次请求(在本例中也就是500中的平均每一次)所需时间 
  38. Transfer rate:          10.32 [Kbytes/sec] received    #这些请求在单位时间内从服务器获取的数据长度 
  39.  
  40. Connection Times (ms) 
  41.               min  mean[+/-sd] median   max 
  42. Connect:        9   46 460.5     11    9060 
  43. Processing:    25 20066 13796.4  14798   36549 
  44. Waiting:       14 16163 15029.9   8460   36484 
  45. Total:         37 20111 13785.1  22804   36562 
  46.  
  47. Percentage of the requests served within a certain time (ms) 
  48.   50%  22804     #50%用户请求在22804ms内返回 
  49.   66%  33043    #66%用户请求在33043ms内返回 
  50.   75%  34181 
  51.   80%  34791 
  52.   90%  35877 
  53.   95%  36416 
  54.   98%  36502    #98%用户请求在36502ms内返回 
  55.   99%  36512 
  56.  100%  36562 (longest request) 

命令参数参考:

  1. -n requests Number of requests to perform //本次测试发起的总请求数 
  2. -c concurrency Number of multiple requests to make   //一次产生的请求数(或并发数) 
  3. -t timelimit Seconds to max. wait for responses    //测试所进行的最大秒数,默认没有时间限制。 
  4. -r Don't exit on socket receive errors.    // 抛出异常继续执行测试任务 
  5. -p postfile File containing data to POST  //包含了需要POST的数据的文件,文件格式如“p1=1&p2=2”.使用方法是 -p 111.txt 
  6. -T content-type Content-type header for POSTing 
  7. //POST数据所使用的Content-type头信息,如 -T “application/x-www-form-urlencoded” 。 (配合-p) 
  8. -v verbosity How much troubleshooting info to print 
  9. //设置显示信息的详细程度 – 4或更大值会显示头信息, 3或更大值可以显示响应代码(404, 200等), 2或更大值可以显示警告和其他信息。 -V 显示版本号并退出。 
  10. -C attribute Add cookie, eg. -C “c1=1234,c2=2,c3=3” (repeatable
  11. //-C cookie-name=value 对请求附加一个Cookie:行。 其典型形式是name=value的一个参数对。此参数可以重复,用逗号分割。 
  12. 提示:可以借助session实现原理传递 JSESSIONID参数, 实现保持会话的功能,如-C ” c1=1234,c2=2,c3=3, JSESSIONID=FF056CD16DA9D71CB131C1D56F0319F8″ 。 
  13. -w Print out results in HTML tables  //以HTML表的格式输出结果。默认时,它是白色背景的两列宽度的一张表。 

2.5 使用注意

1、MAC中自带了Apache。

2、在使用ab命令时,并发了过高会出现错误:Too many open files,由于系统打开文件数量限制了具有轻量化特点的bench还是很适合中小企业使用,尤其在于模拟访问页面的多机测试

三、JMeter:Apache组织开发的压力测试工具(使用比较多的工具)

3.1 简介

Apache JMeter是一款纯java编写负载功能测试和性能测试开源工具软件。相比Loadrunner而言,JMeter小巧轻便且免费,逐渐成为了主流的性能测试工具,是每个测试人员都必须要掌握的工具之一

JDK版本:1.8 运行环境:Windows 7 64 JMeter版本:3.3

注意:安装JMeter需要 Java8和8以上的JDK版本

3.2 JDK安装(如果已经安装JDK 1.8 忽略这一步)

1、jdk官网下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html

2、选择 Java SE 8u231,点击JDK下载


安装下载的JDK

配置系统环境变量 具体可以自行查找资料,这里就不做过多描述

3.2 JMeter安装

1、官网下载地址:JMeter地址:http://jmeter.apache.org/download_jmeter.cgi

2、下载最新JMeter 5.1.1 版本:Apache JMeter 5.1.1 (Requires Java 8+)

3、下载完成后解压zip包,双击bin目录下jmeter.bat文件


3.3 JMeter 使用

1、双击bin目录下jmeter.bat文件后,打开Apache JMeter工具


2、案例测试(Test Plan - > Add - > Thread(User) - > Thread Group)

3、设置名称和线程数


线程参数解读:Number of Threads (users):虚拟用户数(也就是线程数),一个虚拟用户占用一个进程或线程Ramp-Up Period(in seconds):准备时长,设置的虚拟用户数需要多长时间全部启动。

Loop Count:循环次数每个线程发送请求的次数

如果线程数为20,循环次数为100,那么每个线程发送100次请求。总请求数为20*100=2000 。

如果勾选了“Forever”,那么所有线程会一直发送请求,一到选择停止运行脚本。

Delay Thread creation until needed:直到需要时延迟线程的创建

Scheduler:调度器,设置线程组启动的开始时间和结束时间(配置调度器时,需要勾选循环次数为永远)

Duration(Seconds):持续时间(秒),测试持续时间,会覆盖结束时间

Startup delay(Seconds):启动延迟(秒),测试延迟启动时间,会覆盖启动时间

4、添加Http请求

右键点击,Htto请求 > Add > Sampler > Http Request

接下来我们对接口 https://www.baidu.com/s?ie=UTF-8&wd=edg进行性能测试,如下图所示:


请求参数详解:

  • Web Server(Http服务): 1、Protocol[http]:协议,向目标服务器发送HTTP请求协议,可以是HTTP或HTTPS,默认为HTTP 2、服务器名称或IP:HTTP请求发送的目标服务器名称(域名)或IP 3、Port Number:端口号
  • Http Reuqeset(Http请求体): 1、Method:请求方法类型,有GET、POST、HEAD、PUT、OPTIONS、TRACE、DELETE等 2、path:目标URL路径,除去服务器地址、端口和请求参数后所得到的数据 3、Content encoding:编码方式,设置为 UTF-8
  • 请求参数: 设置请求参数,都在下面的列表中进行设置,
  • 列表参数解读:Name:请求参数名 Value:请求值 URL Encode:是否Url编码 Conten-Type:内容类型,有需要自行调整(一般选择默认即可) include Equals:是否包含等于

注意:参数传入中文时需要勾选“URL Encode”

这里的按钮都是针对列表中的数据进行操作的

  1. Detail 
  2. :查看参数详情 
  3.  
  4. Add 
  5. :添加一行列表请求参数 
  6.  
  7. Delte 
  8. :删除一行数据 
  9.  
  10. Up 
  11. :设置列表参数上移 
  12.  
  13. Down 
  14. :设置列表参数下移 
  15.  
  16. add from  
  17. Clipdoard 
  18. :从我们复制的内容中进行添加 

5、添加察看结果树

1、右键点击 Http请求 > Add > Listener > View Results Tree

2、这里我们设置响应数据格式:HTMLSourceFormatted,点击运行我们就可以看到请求结果


3、本次搜索返回结果页面标题为 edg_百度搜索

6、添加用户自定义变量

1、添加用户自定义变量用以Http请求参数化:Http请求 > Add > Config Element > User Defined Variables


2、新增请求参数,存放搜索关键字


3、在 Http测试请求 中使用该参数,格式为:${wd} ,如下图所示


7、添加响应断言

右键点击 Http测试请求(注意是Http测试请求) > Add > Assertions > Response Assertion

 

校验返回的文本中是否包含搜索词,添加参数${wd}到要测试的模式中

  1. Contains 
  2. :包括 
  3.  
  4. Matches 
  5. :匹配 
  6.  
  7. Equals 
  8. :相等 
  9.  
  10. SubString 
  11. :原谅博主才疏学浅,这个就不做解释了 
  12.  
  13. Not 
  14. :否 
  15.  
  16. or 
  17. :或者 

 

7、添加响应断言结果

右键点击 Http测试请求 > Add > Listener > Assertion Results


点击运行,查询运行结果

8、添加聚合报告

右键点击 Http请求 > Add > Listener > Aggregate Report


到这里我们就完成了一个完整的Http接口的性能测试编写,接下来我们会对它的性能进行测试

3.4 JMeter 性能测试

1、配置Http请求(线程组)信息

点击Http请求(线程组),配置相关的性能测试相关参数线程数:50 循环次数:永远持续时间:60秒


2、执行测试信息

选择聚合报告,查询结构,点击 箭头 按钮启动测试,如果要清楚具体内容,点击小扫把,清除调试结果


3、测试结果分析解读

1、打开聚合报告

参数详解:

  1. Label:每个 JMeter 的 element都有一个 Name 属性,这里显示的是 Name 属性的值
  2. #Samples:请求数——表示这次测试中一共发出了多少个请求 如果模拟10个用户,每个用户迭代10次,那么这里显示100
  3. Average:平均响应时间——默认情况下是单个 Request 的平均响应时间 当使用了 Transaction Controller 时,以Transaction 为单位显示平均响应时间
  4. Median:中位数,也就是 50% 用户的响应时间
  5. 90% Line:90% 用户的响应时间
  6. 99% Line:99% 用户的响应时间
  7. Min:最小响应时间
  8. Max:最大响应时间
  9. Error%:错误率——错误请求数/请求总数
  10. Throughput:吞吐量——默认情况下表示每秒完成的请求数(Request per Second) 当使用了TransactionController时,也可以表示类似LoadRunner的TransactionperSecond数
  11. KB/Sec:每秒从服务器端接收到的数据量

在实际中我们需要关注的点只有—— #Samples 请求数,Average 平均响应时间,Min 最小响应时间,Max 最大响应时间,Error% 错误率和Throughput 吞吐量

四、代码模拟

1、Semaphore

Semaphore是计数信号量。Semaphore管理一系列许可证。每个acquire方法阻塞,直到有一个许可证可以获得然后拿走一个许可证;每个release方法增加一个许可证,这可能会释放一个阻塞的acquire方法。然而,其实并没有实际的许可证这个对象,Semaphore只是维持了一个可获得许可证的数量。

[[380133]]

1.1 代码演示:获取一个许可证

  1. import lombok.extern.slf4j.Slf4j; 
  2.  
  3. import java.util.concurrent.CountDownLatch; 
  4. import java.util.concurrent.ExecutorService; 
  5. import java.util.concurrent.Executors; 
  6. import java.util.concurrent.Semaphore; 
  7.  
  8. @Slf4j 
  9. public class SemaphoreExample1 { 
  10.  
  11.     private final static int threadCount = 20; 
  12.  
  13.     public static void main(String[] args) throws Exception { 
  14.  
  15.         ExecutorService exec = Executors.newCachedThreadPool(); 
  16.  
  17.         final Semaphore semaphore = new Semaphore(3); 
  18.  
  19.         for (int i = 0; i < threadCount; i++) { 
  20.             final int threadNum = i; 
  21.             exec.execute(() -> { 
  22.                 try { 
  23.                     semaphore.acquire(); // 获取一个许可 
  24.                     test(threadNum); 
  25.                     semaphore.release(); // 释放一个许可 
  26.                 } catch (Exception e) { 
  27.                     log.error("exception", e); 
  28.                 } 
  29.             }); 
  30.         } 
  31.         exec.shutdown(); 
  32.     } 
  33.  
  34.     private static void test(int threadNum) throws Exception { 
  35.         log.info("{}", threadNum); 
  36.         Thread.sleep(1000); 
  37.     } 

执行结果:如下图所示,我们看到虽然结果是无序的,但是请求的线程数量是正确的,这里展示的是获取一个许可,同时也释放一个许可,我们可不可以获取多个许可,释放多个许可呢,答案是可以的


1.2 代码演示:获取多个许可证

  1. package com.mmall.concurrency.example.aqs; 
  2.  
  3. import lombok.extern.slf4j.Slf4j; 
  4.  
  5. import java.util.concurrent.ExecutorService; 
  6. import java.util.concurrent.Executors; 
  7. import java.util.concurrent.Semaphore; 
  8.  
  9. @Slf4j 
  10. public class SemaphoreExample { 
  11.  
  12.     private final static int threadCount = 20; 
  13.  
  14.     public static void main(String[] args) throws Exception { 
  15.  
  16.         ExecutorService exec = Executors.newCachedThreadPool(); 
  17.  
  18.         final Semaphore semaphore = new Semaphore(3); 
  19.  
  20.         for (int i = 0; i < threadCount; i++) { 
  21.             final int threadNum = i; 
  22.             exec.execute(() -> { 
  23.                 try { 
  24.                     semaphore.acquire(3); // 获取多个许可 
  25.                     test(threadNum); 
  26.                     semaphore.release(3); // 释放多个许可 
  27.                 } catch (Exception e) { 
  28.                     log.error("exception", e); 
  29.                 } 
  30.             }); 
  31.         } 
  32.         exec.shutdown(); 
  33.     } 
  34.  
  35.     private static void test(int threadNum) throws Exception { 
  36.         log.info("{}", threadNum); 
  37.         Thread.sleep(1000); 
  38.     } 

执行结果:这里我们看到我们设置了获取多个许可同时也释放多个许可,放回的线程数是正确的,同时执行结果也是有序的


2、CountDownLatch

CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用)。CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。使用一个计数器进行实现。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为0时,表示所有的线程都已经完成了任务,然后在CountDownLatch上等待的线程就可以恢复执行任务

 

2.1 代码演示:

  1. import lombok.extern.slf4j.Slf4j; 
  2.  
  3. import java.util.concurrent.CountDownLatch; 
  4. import java.util.concurrent.ExecutorService; 
  5. import java.util.concurrent.Executors; 
  6.  
  7. @Slf4j 
  8. public class CountDownLatchExample1 { 
  9.  
  10.     private final static int threadCount = 200; 
  11.     public static void main(String[] args) throws Exception { 
  12.         int num = 0; 
  13.  
  14.         ExecutorService exec = Executors.newCachedThreadPool(); 
  15.         final CountDownLatch countDownLatch = new CountDownLatch(threadCount); 
  16.  
  17.         for (int i = 0; i < threadCount; i++) { 
  18.             final int threadNum = i; 
  19.             num++; 
  20.             exec.execute(() -> { 
  21.                 try { 
  22.                     test(threadNum); 
  23.                 } catch (Exception e) { 
  24.                     log.error("exception", e); 
  25.                 } finally { 
  26.                     countDownLatch.countDown(); 
  27.                 } 
  28.             }); 
  29.         } 
  30.         countDownLatch.await(); 
  31.         log.info("finish——"+num); 
  32.         exec.shutdown(); 
  33.     } 
  34.  
  35.     private static void test(int threadNum) throws Exception { 
  36.         Thread.sleep(100); 
  37.         log.info("{}", threadNum); 
  38.         Thread.sleep(100); 
  39.     } 

 

通过返回结果我们可以看到,设置的线程数量返回结果数量和我们设置的线程数量200一致

五、总结

postMan:非专业的并发测试,严格来说postMan并不是并发请求,而是串行执行的,postMan更多的是用来测试Http连接的一个工具,是一个很实用的工具

Apache Bench:Apache Bench是 Apache 服务器自带的一个web压力测试工具,简称ab,ab工具小巧简单,上手学习较快,可以提供需要的基本性能指标,但是没有图形化结果,不能监控

JMeter:Apache JMeter 是Apache 组织开发的基于java的压力测试工具。用于对软件做压力测试的工具,它可以用于测试静态和动态资源例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、 数据库, FTP 服务器等等

总的来说,并发测试中,JMeter和Apache Bench是比较好的选择,由于Apache Bench是基于命令行的,ab处理速度更快,而Jmeter更准确,由于Jmeter本身支持断言、可变参数和CSV数据集的输入,能设定更加灵活多变的的测试场景,至于postMan这款工具,用来最多的是用来模拟Http请求的一个,并不是一个专业的并发请求工具。

 

责任编辑:姜华 来源: 牧小码农
相关推荐

2017-01-09 16:06:19

2023-12-14 07:36:16

Java并发原子类

2024-04-22 09:30:24

2012-03-06 11:01:44

Java

2023-02-10 09:40:36

Go语言并发

2014-07-02 09:37:02

模拟并发并发

2017-02-14 10:00:19

Java开发Lock

2024-11-13 15:09:57

Java线程开发

2024-01-31 08:50:41

Guava并发工具

2019-07-25 12:46:32

Java高并发编程语言

2020-02-18 14:05:47

模拟并发Java

2024-09-06 10:48:13

2010-06-08 18:53:43

UML建模工具

2023-10-18 15:19:56

2019-11-19 09:00:38

JavaAND信号量

2011-08-15 11:13:06

IOS开发并发Dispatch Qu

2012-07-06 15:08:14

跨平台工具Netbiscuits

2012-07-06 15:00:03

跨平台工具MoSync

2022-10-12 07:53:46

并发编程同步工具

2010-01-28 17:18:08

Android模拟器s
点赞
收藏

51CTO技术栈公众号