目录

概述

作为一名后端开发人员,熟练掌握一款性能测试工具非常有必要,这样有利于在技术选型时做一些参考。

常见的性能测试工具有:ab,JMeter,LoadRunner,他们都有各自的特点和应用场景:

  1. ab是Apache的一个工具组件,专门用于HTTP服务器测试。
  2. JMeter是一款遵循Apache开源协议的性能测试工具,除了可以用于HTTP服务器性能测试之外,还可以用于FTP,JDBC,LDAP测试等。
  3. LoadRunner是一款商业化性能测试工具,使用相对复杂一些,但是功能非常强大。

下载&安装

http://jmeter.apache.org/download_jmeter.cgi

JMeter是基于Java开发的跨平台性能测试工具,官方提供了2种压缩格式的二进制包(zip和tgz),根据实际情况下载对应文件即可。

安装也非常简单,直接将压缩包解压到指定目录即可,如下示例:

$ tar xzvf apache-jmeter-5.2.1.tgz -C ~/opt

添加JMeter到环境变量PATH中,如下示例:

$ export JMETER_HOME=~/opt/apache-jmeter-5.2.1
$ export PATH=$PATH:$JMETER_HOME/bin

配置好JMeter环境变量之后,在命令行终端中执行命令jmeter即可启动JMeter图形化界面。

实战JMetetr

使用JMeter分为3个步骤:

  1. 准备测试计划
  2. 执行性能测试
  3. 分析测试报告

测试计划简述

所谓测试计划就是一系列测试配置信息的集合,在JMeter中可以将这些配置信息保存为一个脚本文件(后缀名为“.jmx”)。

测试计划中涉及许多配置对象,详见:Elements of a Test Plan,理解这些配置对象是编写JMeter测试计划的前提,各个配置对象的名称及含义解释如下:

  1. Test Plan:测试计划,组织所有配置信息,是其他配置对象的根
  2. Thread Group:线程组,用于并发参数设置
  3. Controller:控制器,驱动着整个测试计划的执行
  4. Sampler:采样器,用于配置指定类型的请求
  5. Assertion:断言,用于对请求结果进行验证
  6. Timer:定时器,可用于对并发进行控制(例如:设置请求结束后是否延迟再次发送请求)
  7. Configuration Element:配置元素,如:HTTP请求默认值(HTTP Request Defaults),随机变量(Random Variable)等等
  8. Pre-Processor Element:请求执行前置处理器
  9. Post-Processor Element:请求执行后置处理器
  10. Listener:监听器,通常用于展示测试结果,也可以用于对响应数据进行处理(比如:将响应结果写入到文件)
  11. Test Fragment:这个元素目前没有实际用途
  12. Non-Test Element:非测试元素,用于设置一些其他参数,不常用

一般来讲,上述对象之间具备嵌套关系,描述如下:

(1)一个测试脚本中只有一个Test Plan对象,并且作为其他对象的根。

(2)在Test Plan下可以有一个或者多个Thread Group(通常只需要有一个即可),可以有一个或者多个Listener,如:View Results Tree(以树型结构展示),还可以配置Assertion,Timer,Configuration Element,Pre Processor,Post Processor,Test Fragment,Non-Test Element。

(3)在Thread Group下可以配置Controller,Sampler,Assertion,Timer,Configuration Element,Pre-Processor,Post-Processor,Test Fragment,Listener。

(4)Controller下可以配置Controller,Sampler,Assertion,Timer,Configuration Element,Pre-Processor,Post-Processor,Listener。

(5)在Sampler下可以配置Assertion,Timer,Configuration Element,Pre-Processor,Post-Processor,Listener。

用一个树型结构来描述各对象之间的嵌套关系如下:

  • Test Plan

    • Thread Group

      • Controller

        • Controller
        • Sampler
          • Assertion
          • Timer
          • Configuration Element
          • Pre-Processor
          • Post-Processor
          • Listener
        • Assertion
        • Timer
        • Configuration Element
        • Pre-Processor
        • Post-Processor
        • Listener
      • Sampler
      • Assertion
      • Timer
      • Configuration Element
      • Pre-Processor
      • Post-Processor
      • Test Fragment
      • Listener
    • Assertion
    • Timer
    • Configuration Element
    • Pre Processor
    • Post Processor
    • Listener
    • Test Fragment
    • Non-Test Element

如上所述,只有Test PlanThread GroupControllerSampler可以嵌套其他对象,而Assertion,Timer,Configuration Element,Pre-Processor,Post-Processor,Listener,Test Fragment和Non-Test Element不能再嵌套子对象。

实际上,在JMeter图形化界面中编辑测试计划时,指定对象下是否可以再嵌套子对象在操作菜单中就做了限制。

如下图所示是一个在实际应用中可能会涉及到的对象嵌套关系配置示例:

并且对象在运行时的执行顺序如下:

  1. Configuration elements
  2. Pre-Processors
  3. Timers
  4. Sampler
  5. Post-Processors (unless SampleResult is null)
  6. Assertions (unless SampleResult is null)
  7. Listeners (unless SampleResult is null)

首先,定时器(Timers),断言(Assertions),前置和后置处理器(Pre,Post-Processors)只有在应用它们的采样器存在时才会运行;

其次,控制器(Controllers)和采样器(Samplers)按照它们在测试计划配置树中出现的顺序执行;

最后,其他对象按照它们出现的范围和类型顺序执行,在一个特定类型的对象范围内,按照它们在测试计划配置树中出现的顺序执行;

上述这一堆阐述重点在于理解各个测试对象的作用,以及在什么位置使用它们,至于对象的执行顺序理解即可,不用死记硬背。

关于JMeter中的组件列表,详见:Introduction

准备测试计划

JMeter的测试计划有2种方式生成:

  1. 手动编写
  2. 录制脚本

最佳实践是针对不同的场景选择对应的测试计划生成方式,比如:对于接口测试使用手动编写可能更加合适,而对于网页的测试,使用录制脚本的方式会更加方便。

编写测试计划

在GUI模式下编辑测试计划时,关键在于理解清楚JMeter中涉及的配置对象的作用,在此基础上就可以借助图形化界面设计测试计划并将其保存为一个脚本文件。

具体的测试计划编写可以参考官方的一个Web测试计划示例:Building a Web Test Plan

设置“Ramp-up period”参数

在手动编写测试计划时,值得注意点的是:线程池参数“Ramp-up period”值一定要设置合理,该参数的设置关系到测试启动时是否会给服务器带来非常大的冲击甚至过载,或者是达不到性能测试的要求。

“Ramp-up period”参数的含义是设置一个时长(单位:秒),使得在Thread Group中设置的线程根据该时长逐步启动。

举例说明:

(1)在Thread Group中设置线程数为10,Ramp-up period参数设置为100s,JMeter将会在100s内逐步启动10个线程,也就是说,每个线程的启动间隔为10s(100s/10),可能最后一个线程启动的时候第一个线程已经结束。

(2)在Thread Group中设置线程数为100,Ramp-up period参数设置为10s,每个线程的启动间隔为0.1s(10s/100),可能在测试刚启动时给服务器产生很大的负载。

综上所述,Ramp-up period参数值不能设置太大,也不能设置太小,JMeter官方文档的解释是:可以将该参数值与线程数设置为相同,或者比线程数略大或稍小即可。

根据经验来讲,一般需要将Ramp-up period参数值设置比线程数略小更加合适。

其他一些关于Ramp-up period参数的设置技巧可以参考:

  1. 关于JMeter线程组中线程数,Ramp-Up Period,循环次数之间的设置概念
  2. JMeter技巧集锦

除了常见的Web测试,JMeter官方也给出了许多其他类型的测试计划示例,详见:User's Manual

录制测试脚本

录制测试脚本就是通过工具自动生成测试测试的方式,在JMeter中这种方式更适合于Web页面测试,但是实践中发现,自动生成的测试用例也很难直接就能用于性能测试,还需要对测试用例做一些调整。

无论怎样,有胜于无,通过脚本录制方式还是能在一定程度上减少手动编辑测试计划的工作量。

在JMeter中录制测试脚本有2种方式:

  1. 使用JMeter自带的Http服务代理功能录制,不同版本的JMter操作界面不同
  2. 借助于插件和第三方工具录制,如:badboy工具,blazemeter插件等等

更多关于录制JMeter测试脚本的实现可以参考如下博客:

1.Jmeter学习笔记五录制脚本

2.JMeter中级篇-1-JMeter自带的录制功能举例

3.利用Jmeter录制脚本的两种方法

4.录制Jmeter脚本的N种方法

5.JMeter中级篇-2-Firefox录制JMeter脚本的方案

执行性能测试

单机测试

通常来讲,使用JMeter进行性能测试不会在GUI模式下进行,GUI图形化界面通常只用来编写测试计划。在GUI模式下调试好测试脚本之后,通过命令行的方式执行测试脚本。

关于JMeter的运行时参数详见Running JMeter

在命令行执行性能测试的常用参数:

-n:非GUI模式

-t:指定测试计划文件路径,可以是相对路径或者绝对路径

-l:输出测试结果文件路径,可以是相对路径或者绝对路径

-e:输出测试报告

-o:测试报告保存目录,可以是相对路径或者绝对路径

示例如下:

$ jmeter -n -t xxx.jmx -l ./yyy.jtl -e -o ./zzz

关于JMeter命令行参数详见:CLI Mode

分布式测试

当在单机环境下使用JMeter无法模拟足够的并发量时,可以使用分布式模式进行压测。

在分布式模式下,存在一个控制节点Master,多个真正执行测试的从节点Slave,在Master上控制多个Slave进行压力测试。

具体实现:

  1. 启动Slave:在Slave节点启动JMeter服务器模式,进入到JMETER_HOME/bin目录下,执行:jmeter-server或jmeter-server.bat
  2. 启动Master:

    (1)在Master节点上,进入到JMETER_HOME/bin目录下,编辑jmeter.properties文件,将参数“remote_hosts”设置为以逗号分隔的Slave节点IP列表

    (2)在Master启动Slave节点:jmeter -n -t xxx.jmx -r

关于分布式模式运行JMeter详情参考:

  1. Apache JMeter Distributed Testing Step-by-step
  2. Server Mode

分析测试报告

JMeter从3.0之后就支持自动生成测试报告,只需要在执行测试时指定参数“-e”和“-o”即可,“-e”参数设置需要自动生成测试报告,“-o”参数指定测试报告目录(该目录不能已经存在)。

举个例子:jmeter -n -t xxx.jmx -l ./yyy.jtl -e -o ./zzz

当然,还可以使用“-l”参数产生的测试结果文件生成测试报告:jmeter -g ./yyy.jtl -o ./zzz(这种报告生成方式非常有用,例如:运行JMeter压测的机器性能不够好时,在并发量很高的情况下自动生成测试报告会非常慢,此时可以在执行测试的时候只保存测试结果文件,然后将测试结果文件下载到性能更好的机器上再通过命令行的方式手动生成测试报告)。

关于JMeter生成测试报告还可以参考如下文章:

1.JMeter-自动生成测试报告

2.Generating Report Dashboard

性能测试中,我们最关心的指标是吞吐量和响应时间,在JMeter生成的测试报告中,已经非常人性化地展示了这些指标。

APDEX

这是由APDEX公司推出的表示应用程序性能满意度的指标,值范围为:0-1,因此,满意度越接近1说明应用程序的性能越好。

在实际应用中,这个指标仅仅只能作为应用程序性能的一个非常粗略的判断依据,因为在性能测试过程中还要考察响应时间的大小。比如:在一次压测过程中所有请求都得到了响应,此时满意度可能为0.99,但是99%的请求响应时间为1分钟,这显然是不可接受的。

响应时间和吞吐量统计

在JMeter生成的测试报告中有一个关于响应时间和吞吐量的统计报告,如下图所示:

首先,需要关注的是99%的请求响应时间(99th pct)统计,会把所有请求的响应时间做统计对比,通过该指标值可以非常明确地知道接口性能是否达标,如果响应时间不满足要求,则需要考虑是否进行优化。

其次,当响应时间符合预期时还可以看到接口的吞吐量(Throughput),即:每秒请求数。

测试结果详细报表

在JMeter性能测试报告中,关于响应时间和吞吐量的统计概要也只是一个非常粗略的参考指标,这个统计数据会受到测试用例在启动和结束时的干扰,更加详细和准确的统计结果应该查看图形化的报表,非常直观。

  1. Response Times Over Time:响应时间
  2. Active Threads Over Time:并发线程数
  3. Transactions Per Second:每秒事务数,可以理解为每秒请求数
  4. Response Time Vs Request:响应时间与请求数的对比
  5. Response Time Percentiles:响应时间百分比
  6. Response Time Distribution:响应时间分布

关于测试结果统计报表的解读可以参考:JMeter-自动生成测试报告

常用插件及扩展

JMeter自带的功能基本可以完成一些常见的性能测试任务,如果需要实现一些功能更加强大的测试,可以通过插件的方式进行扩展。

JMeter安装插件有2种方式:

(1)通过插件管理器下载,实际上JMeter的插件管理器本身也是一个插件,详见:https://jmeter-plugins.org/install/Install/

(2)手动下载,将插件包下载到$JMETER_HOME/lib/ext目录,重启JMeter即可。

1.Concurrency Thread Group

相比起JMeter自带的Thread Group,该插件可以模拟更加真实的用户并发,也可以很方便地对压测时间进行设置。

2.HTTP Raw Request

功能比JMeter自带的Http Request有增强和优化。

3.Raw Data Source

支持从文件中读取数据,这样可以方便造一些压测需要的数据。

4.Transaction Throughput vs Threads

查看线程数与吞吐量的对比关系,可以非常直观地看到系统性能随着并发数的提高而产生的变化。

更多JMeter插件可以从JMeter Plugins下载。

除了丰富的插件,更多关于JMeter的最佳实践可以参考:Best Practices

关于对JMeter的扩展,详见:How to write a plugin for JMeter

Q&A

Q1: java.net.NoRouteToHostException: Cannot assign requested address

原因: 由于linux分配的客户端连接端口用尽,无法建立socket连接所致,虽然socket正常关闭,但是端口不是立即释放,而是处于 TIME_WAIT 状态,默认等待60s后释放。

查看linux支持的客户端连接端口范围,也就是28232个端口。cat /proc/sys/net/ipv4/ip_local_port_range,端口范围:32768 - 61000

解决:

1.调低端口释放后的等待时间,默认为60s,修改为15~30s。echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout

2.修改tcp/ip协议配置,通过配置/proc/sys/net/ipv4/tcp_tw_reuse,默认为0,修改为1,释放TIME_WAIT端口给新连接使用:echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse

3.修改tcp/ip协议配置,快速回收socket资源,默认为0,修改为1。echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle

即总共需要执行如下命令:

$ echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
$ echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
$ echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout

另外,如果非root用户执行上述命令时可能会遇到权限错误:

$ echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
bash: /proc/sys/net/ipv4/tcp_tw_reuse: Permission denied

甚至在命令之前加上sudo再执行也依然报错:

$ sudo echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
bash: /proc/sys/net/ipv4/tcp_tw_reuse: Permission denied

此时应该通过另外的方式执行:

$ sudo bash -c 'echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse'
$ sudo bash -c 'echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle'
$ sudo bash -c 'echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout'

Q2: 使用JMeter发送POST请求时中文参数在服务器端接收到时为乱码

解决: 在Jmeter中设置“Content-encoding”为:utf-8 。

【参考】

http://www.cnblogs.com/fnng/archive/2012/12/22/2829479.html JMeter基础之一 一个简单的性能测试

https://www.testwo.com/article/357 使用JMeter进行负载测试——终极指南

http://www.cnblogs.com/qmfsun/p/6381767.html JMeter执行压测输出HTML图形化报表(二)

https://my.oschina.net/ydsakyclguozi/blog/536416 Jmeter中的几个重要测试指标释义

https://moonbingbing.gitbooks.io/openresty-best-practices/flame_graph.html 火焰图

https://my.oschina.net/shichangcheng/blog/1560864 JMeter 进行压力测试

https://blog.csdn.net/wwq_1111/article/details/59512546 JMeter压力测试遇到的问题汇总

https://www.infoq.cn/article/k9kx0RxEbhht*iluT9iV 推荐几款常用的性能测试工具

https://www.edureka.co/blog/what-is-software-testing/ 涉及软件测试的文章博客

http://blog.csdn.net/lzqinfen/article/details/46326281 JMeter报错the target server failed to respond--JMeter的坑

https://www.jianshu.com/p/130c7fddeddf Jmeter-使用Stepping Thread Group插件来设置负载场景

http://www.cnblogs.com/YatHo/p/6092599.html jmeter压力测试报告 - DEMO

JMeter入门介绍的更多相关文章

  1. jmeter入门案例(二)

    jmeter入门简介(一)下载及元件介绍https://www.cnblogs.com/wish5714/p/9714930.html jmeter典型的http请求示例 业务场景 银行卡收单交易,模 ...

  2. 性能测试基础---jmeter入门

    ·Jmeter入门 ·Jmeter的简介: ·Jmeter是一款基于纯JAVA语言开发的开源的性能测试工具. ·Jmeter的下载: ·最新版:http://jmeter.apache.org/dow ...

  3. C# BackgroundWorker组件学习入门介绍

    C# BackgroundWorker组件学习入门介绍 一个程序中需要进行大量的运算,并且需要在运算过程中支持用户一定的交互,为了获得更好的用户体验,使用BackgroundWorker来完成这一功能 ...

  4. 初识Hadoop入门介绍

    初识hadoop入门介绍 Hadoop一直是我想学习的技术,正巧最近项目组要做电子商城,我就开始研究Hadoop,虽然最后鉴定Hadoop不适用我们的项目,但是我会继续研究下去,技多不压身. < ...

  5. [Python爬虫] 在Windows下安装PhantomJS和CasperJS及入门介绍(上)

    最近在使用Python爬取网页内容时,总是遇到JS临时加载.动态获取网页信息的困难.例如爬取CSDN下载资源评论.搜狐图片中的“原图”等,此时尝试学习Phantomjs和CasperJS来解决这个问题 ...

  6. [Python爬虫] scrapy爬虫系列 <一>.安装及入门介绍

    前面介绍了很多Selenium基于自动测试的Python爬虫程序,主要利用它的xpath语句,通过分析网页DOM树结构进行爬取内容,同时可以结合Phantomjs模拟浏览器进行鼠标或键盘操作.但是,更 ...

  7. JMeter入门合集

    JMeter从入门到精通 http://blog.csdn.net/lihengxin/article/details/4325918 jmeter入门教程- Jmeter教程及技巧汇总 http:/ ...

  8. JavaScript入门介绍(二)

    JavaScript入门介绍 [函数] 函数function 是Javascript的基础模块单元,用于代码的复用.信息影藏和组合调用. function a(){} 函数对象Function Lit ...

  9. JavaScript入门介绍(一)

    JavaScript入门介绍 [经常使用的调试工具][w3school.com.cn在线编辑] [Chrome浏览器 开发调试工具]按F121.代码后台输出调试:console.log("t ...

随机推荐

  1. P1102 A-B 数对

    P1102题库链接:https://www.luogu.org/problem/P1102 难度:普及- 算法标签:模拟,数论,排序,HASH,概率论,二分查找 1.朴素 O(n^2) 得分76 将输 ...

  2. LeetCode python实现题解(持续更新)

    目录 LeetCode Python实现算法简介 0001 两数之和 0002 两数相加 0003 无重复字符的最长子串 0004 寻找两个有序数组的中位数 0005 最长回文子串 0006 Z字型变 ...

  3. volatile和synchronized到底啥区别?多图文讲解告诉你

    你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it well enough ...

  4. 用vue + leancloud开发一个免费的博客

    项目地址 https://github.com/Fee-ing/Fe... 在线预览 在线预览地址: 搭建免费博客

  5. a标签嵌套href默认行为与子元素click事件存在影响

    2018-08-07 Question about work 开发过程中遇到问题,简单写个demo 运行环境为Chrome 68 描述一下这个问题,当<a>标签内部存在嵌套时, 父元素&l ...

  6. DirectX11--深入理解Effects11、使用着色器反射机制(Shader Reflection)实现一个复杂Effects框架

    前言 如果之前你是跟随本教程系列学习的话,应该能够初步了解Effects11(现FX11)的实现机制,并且可以编写一个简易的特效管理框架,但是随着特效种类的增多,要管理的着色器.资源等也随之变多.如果 ...

  7. python学习-练习题1巩固(随机数)

    1.生成随机数 random.random()生成一个0-1之前的随机数

  8. vue中数据请求的三种方法

    注意请求可能存在跨域问题,需要去配置好 这三种建议使用axios 1.resource Vue 要实现异步加载需要使用到 vue-resource 库. Vue.js 2.0 版本推荐使用 axios ...

  9. RocketMQ-2.RocketMQ的负载均衡

    目录 RocketMQ的负载均衡 producer对MessageQueue的负载均衡 producer负载均衡 系统计算路由MessageQueue 自定义路由MessageQueue Consum ...

  10. BFC块级格式上下文介绍

    块级格式上下文(Block formatting context) 什么是BFC? 块格式化上下文(block formatting context) 是页面 CSS视觉渲染的一部分.它是用于决定块盒 ...