玖叶教程网

前端编程开发入门

程序员也该学习一下Web性能测试解决方案:JMeter

Web性能测试解决方案:JMeter问题描述

在代码写好之后,通常需要对场景进行性能测试,例如购买商品场景、登录场景、支付场景等,此阶段会出现的典型问题如下:

(1)当前登录场景可能需要调用N个接口,每天高峰期的时候,应用程序可以承受多少人登录。

(2)秒杀系统最多可以让多少人同时单击“购买”按钮而不出现异常。

(3)连续100小时以上的疲劳测试是否会使系统内存出现无法下降、GC无法回收内存、疲劳测试之后CPU无法正常下降等问题。

(4)在并发压力下,应用程序哪里消耗资源过多,需要进行优化?

(5)在复杂场景下,整体接口包含调用逻辑,其中可能包括if-else判断、for/while循环、获取上一个接口的信息传输到下一个接口中等操作,如何简化这部分性能测试的需求?

(6)针对协议如何进行测试?例如HTTP轮询与WebSocket哪个更消耗性能?大概相差多少?

(7)当单台压力机无法生成更大的压力时,如何增加压力机?

问题分析与解决方案

针对上面提出的问题,全部可以通过JMeter解决。

JMeter是100%完全由Java编写的对软件进行性能测试的桌面程序,其桌面GUI部分可方便用户用无代码的方式编写性能测试脚本。待测试脚本编写完成之后,通常使用后台启动JMeter的方式运行性能测试脚本(因为GUI消耗资源过多)。

与JMH不同的是,JMeter通常以多个代码单元组合成场景,模拟真正用户进行操作的调用顺序进行测试,其结果更加符合上线后的实际需求。也就是说,JMeter更擅长对项目整体进行测试与优化,而JMH更擅长对代码局部进行测试与优化。

JMeter的特点

JMeter可以对多种协议进行性能测试,包括并不限于HTTP、HTTPS、WS、WSS、TCP、UDP、SOAP和FTP。除此之外,还可以对NoSQL、MySQL、JMS等数据源或容器进行性能测试。

除编写性能测试脚本外,JMeter还支持使用脚本录制的方式进行性能测试,即通过网页代理进行页面上的操作,其操作流程会被直接录制下来,并自动转换成性能测试脚本。此后每次测试时,只需直接使用脚本进行性能测试即可。在JMeter脚本录制的辅助下,再困难的业务逻辑也可以轻松地进行测试。

JMeter具有制作良好的GUI,即便初次接触的人,也可以迅速理解它并进行操作。

JMeter具有各种可插拔的插件,因为JMeter的应用范围较为广泛,所以插件数量庞大。其插件完全由Java语言编写,方便因特殊业务逻辑进行自我扩展。

JMeter包含各种断言、采样器等功能,方便用户在性能测试过程中,获取接口返回值,并对返回值进行参数化处理。例如,在调用接口2时,使用从接口1处返回的数值。

除性能测试外,JMeter在CI/CD领域也可以配合其他工具实现接口自动化测试架构,如JMeter+Ant+Jenkins等。

深入理解JMeter-JMeter中的部分配置元件

取样器(Sampler):取样器是JMeter的基础单元,通常各种协议的请求皆由取样器发起。例如,HTTP请求、FTP请求、JMS发布与订阅、Java请求、LDAP请求、JDBC请求、TCP请求、SMTP请求和WebSocket请求(需下载额外插件)等。

配置元件(ConfigurationElement):配置元件主要对取样器中的各种请求进行辅助配置。例如,HTTP信息头管理器、HTTP缓存管理器、HTTPCookie管理器、JDBC连接配置、LDAP扩展请求、FTP默认请求、TCP取样器配置等。另外,在配置元件中还包含一些与测试计划相关的配置元件,主要包括计数器、用户定义的变量等。

逻辑控制器(Logic Controller):逻辑控制器主要控制JMeter脚本的执行顺序。例如,从接口1处请求得到的结果,经过逻辑控制器判断之后,会控制执行到接口2或接口3。逻辑控制器的存在使得整体测试的灵活度更高。

逻辑控制器中主要包含if控制器、事务控制器、循环控制器、While控制器、临界部分控制器、ForEach控制器、仅执行一次控制器、吞吐量控制器和Switch控制器等。

前置处理器(Pre-Processor):在执行取样器之前,需执行前置处理器。前置处理器主要包括HTML链接解释器、HTML URL重写修饰符和取样器超时等。

后置处理器(Post-Processor):在执行取样器之后,需执行后置处理器。后置处理器主要包括CSS/JQuery提取器、JSON提取器、边界提取器、BeanShell断言和正则表达式提取器等。这些后置处理器在提取数据之后,可对上一个请求得到的结果进行参数化,并传输到下一个请求中。

断言(Assertion):断言可用来验证服务器返回的数据与预期是否相符,如果不相符,可以记录或停止测试计划。断言主要包括响应断言、JSON断言、大小断言、HTML断言、XML断言和BeanShell断言等。

定时器(Timer):在测试计划执行过程中,定时器主要用来减缓线程运行。例如,线程在请求接口1执行之后,需暂停若干ms之后再请求接口2。定时器主要包括固定定时器和随机定时器等。

监听器(Listener):监听器主要用来收集测试结果报告。监听器主要包括:察看结果树、断言结果和聚合报告等。另外,在下载插件之后,还可以监听被测试端机器的CPU和内存等信息。

JMeter的功能繁多,本章内容仅为抛砖引玉。JMeter除自身所带功能外,还可通过添加jar包的方式,增加更多的配置元件、请求方式等。若某些测试场景连扩展功能都无法满足,则可自行编写Java程序对接的JMeter接口,生成jar包,并在JMeter中当作扩展的配置原件进行使用。

JMeter参数化的实现方式

JMeter参数化的实现方式如下:

? JMeter函数:JMeter函数指GUI界面→工具→函数助手对话框中JMeter自带的函数内容,主要包括Random(随机数字)、RandomString(随机字符串)、RandomDate(随机时间)、splt(字符串拆分)、property(自定义数值)、UUID和char等。

? JMeter读取外部文件:读取外部配置文件的方式较多,包括JMeter函数 中 的 StringFromFile ( 从 文 件 中 读 取 字 符 串 ) 、 配 置 元 件 中 的CSVDataSetConfig(从CSV文件中读取配置信息)等。

? JMeter提取上一个接口返回值:通常通过后置处理器中的BeanShell断言、JSON提取器和正则表达式提取器等方式提取相应返回值。

JMeter在提取数据后,需要在HTTP请求脚本中通过${变量名称}的形式使用参数化变量,并且除请求body外,在任何地方都可以使用变量名称。例如,路径、服务器名称或IP地址、端口号、协议和编码等。

JMeter函数

JMeter函数的位置如图5-1所示。

JMeter函数助手对话框如图5-2所示。

在配置相应内容之后,可单击“生成”按钮,生成相关函数,如图5-3所示。

此次示例中使用的是RandomString函数。在Charts to use for randomstring generation对话框中随机输入若干数字、字母、汉字,此函数会随机拆分。在Random string length中,从The result of the function is对话框中可以看到该函数的返回结果。复制生成的函数,即可在请求中进行使用,如图5-4所示。

从察看结果树处或后台处可以看到已经发送过去了一段随机字符串,如图5-5所示。

通过JMeter读取外部文件

创建a.csv文件,如图5-6所示。

在测试计划中添加CSV Data Set Config(CSV数据文件设置器),如图5-7所示。

配置之后,读取a.csv文件中的数据并编写HTTP请求部分的内容。

通过JMeter提取上一个接口返回值

为方便测试,下面更改代码,如图5-8所示。

在测试计划中添加JSON提取器,如图5-9所示。编写JSON提取器的相应规则,在Names of created variables后面的文本框中填写需要在HTTP请求中编写的变量名称,在JSON Path expressions后面的文本框中填写JSON的value值映射,如图5-10所示

配置之后,读取接口中的数据并进行HTTP请求部分的编写,此时整体测试计划应如图5-11所示。getAge的请求结果如图5-12所示。

JMeter实战-初次使用JMeter测试REST接口

从官网下载JMeter的5.4.1版本之后,直接运行JMeter.bat文件,即可在Windows 系 统 下 打 开 JMeter 的 GUI 控 制 页 面 , 单 击Options→ChooseLanguage→Chinese(Simplified)选项,修改显示语语,如图5-13所示。

在修改显示语言之后,在Test Plan(测试计划)下添加线程组,如图5-14所示。

线程组窗口如图5-15所示。

? 线程数:指此次测试总共开启的线程数。

? Ramp-Up时间(秒):表示在多长时间内开启所有的线程数。若该时间设置过长,则可能导致在刚启动时请求压力不足,平均结果不符合实际预期。若该时间设置过短,则可能导致在刚启动时请求压力过大,服务器直接崩溃。该时间应根据具体项目进行设置,通常设置为线程数的10%即可。

? 循环次数:指整体线程组的循环执行次数,通常请求的事务总数为线程数×循环次数。

? 调度器:需要配合“循环次数”和“永远”选项同时使用,即不按循环次数进行执行线程,而是根据时间循环所有线程。该方式为性能测试的常见方式,通常在调试完脚本之后,选择调度器增加持续时间即可。在使用调度器之后,线程会尽可能地执行,所以其总事务数没有预期,可在执行时长之后,从聚合报告上查看总事务数。

在添加线程组之后,需添加HTTP请求的取样器,如图5-16所示。

HTTP请求窗口如图5-17所示。HTTP请求的取样器的使用方式与Postman几乎没有差别,只需按规定输入相关的内容即可。

部分HTTP请求需配置HTTP请求头,即在HTTP请求头中输入token之类的内容。此时可在HTTP请求的级别下,添加HTTP信息头管理器配置元件,在配置元件中编写相关内容,如图5-18所示。

在针对HTTP请求相关内容进行配置之后,需要对整体测试结果进行监控,通常使用察看结果树和聚合报告对测试结果进行监控,如图5-19所示。

在察看结果树中可以看到每次请求的请求值与返回结果等相关信息。在高并发测试下,由于数据量过大,建议在察看结果树中进行配置,使其只返回错误的结果即可。

聚合报告中包含总请求事务数、中位数与百分位的响应时间、异常数量与异常所占百分比、吞吐量、接收与发送的每秒带宽占用量等。

值得注意的是,察看结果树需通常放置在HTTP请求的下一级别或同一级别中,而聚合报告需要与HTTP请求处于同一级别。这是因为如果在测试计划中包含多个HTTP请求,并且聚合报告处于HTTP请求之下,则聚合报告只返回该HTTP请求的响应情况,不会返回多个HTTP请求的整体情况。

前面已经配置好了一个包含HTTP请求的压力测试脚本,保存这个压力测试脚本即可。

在GUI模式下启动JMeter,如图5-20所示。

察看结果树的返回结果如图5-21和图5-22所示。

此时已确定该脚本是可以正常运行的,下面增加线程组的线程数并配置调度器,再次保存脚本,并使用非GUI模式(命令行模式)启动JMeter,命令如下所示:

命令解析如下所示:

? -h:帮助,打印出有用的信息并退出。

? -n:在非GUI模式下运行JMeter。

? -t:要运行的JMeter测试脚本文件。

? -l:输出日志文件,即记录结果的文件。此时所编写的为要输出的文件名称,在原来的文件夹中不需要包含这个文件。

? -r:远程执行,在Jmter.properties文件中指定所有远程服务器。

? -H:设置JMeter使用的代理主机。

? -P:设置JMeter使用的代理主机的端口号。

在执行JMeter命令后,结果如图5-23所示。

生成的日志文件如图5-24所示,其中a.jmx文件为JMeter测试脚本文件,a.jtl文件为JMeter测试报告。

可通过聚合报告中的浏览按钮打开图5-24中生成的测试报告,如图5-25所示。

如果在编写脚本时出现错误,则可以通过选项菜单下的日志查看功能,查看JMeter的具体报错内容,如图5-26与图5-27所示。

录制性能测试脚本

录制性能测试脚本指通过在页面单击的形式,记录所有的请求信息,包括HTTP内响应信息与响应头等。录制性能测试脚本是性能测试过程中最常用的技术,在录制性能测试脚本之后,会对其参数进行微调,然后使用该脚本进行性能测试。

通常使用JMeter自带的HTTP代理服务器录制性能测试脚本,除此之外,还可以使用BadBoy工具对页面进行录制,并通过BadBoy工具将录制的脚本另存为.jmx文件。下面在JMeter中添加HTTP代理服务器,如图5-28所示。

在HTTP代理服务器中可编写自定义的代理端口号,并在目标控制器中进行配置。目标控制器指该次录制的脚本将放置在哪个线程组中。在配置结束后单击启动按钮即可,如图5-29所示。

在搭建好JMeter的代理服务器之后,需配置本地计算机的Internet属性,增加代理服务器与刚自定义的端口号,如图5-30所示。此后随意单击一些页面即可看到通过代理服务器进行请求的接口都已录制到线程组中,如图5-31所示。

(1)编写JMeter脚本,一台JMeter模拟正常用户正在使用,另一台JMeter模拟登录,将模拟登录的JMeter性能提高一些。最后得到的JMeter报表即为当前应用程序可以承受的最大压力。

(2)该测试可将JMeter的压力开到最大,同时监控秒杀系统的CPU和内存是否出现异常,并定时检查不同数据源的数据是否保持数据一致性,即可得知当前秒杀系统可承载多大的压力。

(3)该测试需要服务器不断运行,在运行之后查看JVM的GC信息、CPU与内存信息,确保程序上线后,在长时间运行的情况下,可以将使用的内存正常回收起来。很多程序在刚运行的时候是没有问题的,但是无法长时间运行,此测试就是针对这种情况进行的。

(4)该测试需要编程人员在测试过程中使用Arthas等相关工具,监控当前测试的接口,了解线程消耗。例如,当前使用Redisson操作Redis,则需要查看Redisson实际开启了多少个Thread线程,并且每个线程消耗了多少CPU与内存。或查看某个接口中哪个子函数的响应速度最慢。这种优化类的测试属于细致类的工作,需要大量的时间进行排查,以提高应用程序的单节点性能(纵向优化)。

(5)可以用JMeter脚本录制的方式,通过JMeter自带的网络代理在网页上仿照正常用户单击网页即可获得完整的JMeter脚本,只需调整一下JMeter参数化传递即可。

(6)通过不同的JMeter插件即可完成对不同协议的测试。JMeter官方地址包含大部分协议与工具的插件应用,并且配备了相关教程,十分方便。

(7)当单台JMeter无法增加更大压力时,可部署JMeter集群。

本文给大家讲解的内容是Web性能测试解决方案:JMeter

  • 下文给大家讲解的是SQL优化与索引优化

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言