1.背景介绍 什么是压测?
压力测试是通过不断向被测系统施加“压力”,测试系统在压力情况下的性能表现,考察当前软硬件环境下系统所能承受的最大负荷并帮助找出系统瓶颈所在,也就是我们可以模拟巨大的工作负荷以查看应用程序在峰值使用情况下如何执行操作。 为什么要进行压力测试? 压力测试其实有两个目的,一是测试应用在高并发情况下是否会报错,进程是否会挂掉; 二是测试应用的抗压能力,预估应用的承载能力,为后面的运维提供扩容的依据。第一点很好理解,做好这一点就可以保证上线之后不出问题了。解释下第二点,我们都知道就是架构设计的再优秀,代码写的再好,应对高并发单实例始终是有限的。所以通常是在满足第一点的前提下,再根据可能到来的高并发压力来计算需要多少实例来承载,而这就需要我们压出极限。 接口开发完成之后就可以进行第一次压力测试。这一次压力测试可以简单压一下, 在本机进行就可以。压力测试的目的是检查代码在高并发下是否会报错。另外,编译型语言要观察是否存在内存泄漏。 因为本机性能有限,一般来说按照100、200、300、500进程数进行压力测试,压到500如果没有报错就可以进行疲劳测试,观察内存占用。
2.知识剖析 什么Jmeter?
Jmeter 是一款使用Java开发的,开源免费的,测试工具, 主要用来做功能测试和性能测试(压力测试/负载测试).而且用Jmeter 来测试 Restful API, 非常好用。同时,JMeter可以帮助你对你的应用程序进行回归测试。通过你创建的测试脚本和assertions来验证你的程序返回了所期待的值。为了更高的适应性,JMeter允许你使用正则表达式来创建这些assertions. 压力测试的关键名词 1、Test Plan (测试计划):
用来描述一个性能测试,包含与本次性能测试所有相关的功能。也就说本次性能测试的所有内容都是基于一个计划的。
2、Threads (Users)线程 用户 1) setup thread group 可用于执行预测试操作。这些类型的线程执行测试前进行定期线程组的执行。 2) teardown thread group. 可用于执行测试后动作。这些类型的线程执行测试结束后执行定期的线程组。 3) thread group(线程组). 这个就是我们通常添加运行的线程。通俗的讲一个线程组,,可以看做一个虚拟用户组,线程组中的每个线程都可以理解为一个虚拟用户。 线程组中包含的线程数量在测试执行过程中是不会发生改变的。 Ramp-Up Period:单位是秒,默认时间是1秒。它指定了启动所有线程所花费的时间, 如果你需要Jmeter立即启动所有线程,将此设定为0即可 循环次数:表示每个线程执行多少次请求。
3、采样器(Samplers)它们是每一个测试计划的基本要素,一切都围绕这些采样器而工作:采样器执行请求(基于配置的请求),这些请求产生一个或多个响应,后续将被分析。
4、监听器(Listeners):负责收集测试结果,同时也被告知了结果显示的方式。 监听器以报表、树型结构、或简明的日志文件的形式分析结果。 功能是对取样器的请求结果显示、统计一些数据(吞吐量、KB/S……)等。
5、断言(Assertions):用于来判断请求响应的结果是否如用户所期望,是否正确。断言一般用来设置检查点,用以保证性能测试过程中的数据交互是否与预期一致。
6、定时器(Timers):负责定义请求(线程)之间的延迟间隔,模拟对服务器的连续请求。用于操作之间设置等待时间,等待时间是性能测试中常用的控制客户端QPS的手段。如果不指定,JMeter会一个请求完成后立即执行下一个请求,没有任何等待时间。 7、逻辑控制器(Logic Controllers):允许自定义JMeter发送请求的行为逻辑,它与Sampler结合使用可以模拟复杂的请求序列。 8、前置处理器和后置处理器负责在生成请求之前和之后完成工作。前置处理器常常用来修改请求的设置,后置处理器则常常用来处理响应的数据。
9、配置节点(Configuration nodes) 通过使用配置元素你可以将不同的参数传递给取样器请求。他们提供了创建变量(不同的和动态的)的一种方式,这些参数之后被采样器所使用。在采样器被执行前,参数所属节点启动时,这些参数被执行;这就是为什么采样器可以依赖这些变量。 测试计划元素执行顺序 1–配置节点 2–前置处理器 3–定时器 4–取样器 5–后置处理器(只在有结果可用情况下执行) 6–断言(只在有结果可用情况下执行) 7–监听器(只在有结果可用情况下执行) 3、常见问题 1.吞吐量与带宽的区分 4、解决方案 1.吞吐量与带宽的区分 吞吐量和带宽是很容易搞混的一个词,两者的单位都是Mbps.先让我们来看两者对应的英语, 吞吐 量:throughput ; 带宽: Max net bitrate 。当我们讨论通信链路的带宽时,一般是指链路上每秒所能传送的比特数。我们可以说以太网的带宽是10Mbps。但是,我们需要区分链路上的可用带宽(带 宽)与实际链路中每秒所能传送的比特数(吞吐量)。我们倾向于用“吞吐量”一次来表示一个系统的测试性能。这样,因为实现受各种低效率因素的影响,所以由 一段带宽为10Mbps的链路连接的一对节点可能只达到2Mbps的吞吐量。这样就意味着,一个主机上的应用能够以2Mbps的速度向另外的一个主机发送 数据。 5.编码实战 6.扩展思考 如何正确做web应用的压力测试 1) 首先说一下如何产生压力,产生压力的方法有很多,通常可以写脚本产生压力机器人对服务器进行发包和收包操作,也可以使用现有的工具(像jmeter、LoadRunner这些),所以说产生压力其实并不难,难点在于产生的压力是不是真实地反映了实际用户的操作场景。 举个例子来说,对游戏来说单纯的并发登陆场景在整个线上环境中的占比可能并不大(新开服等特殊情况除外),相反“登陆-开始战斗-结束战斗”、不同用户执行不同动作这种“混合模式”占了更大的比重。所以如何从实际环境中提炼出具体的场景比重,并且把这种比重转化成实际压力是一个重要的关注点。 2)产生压力之后,通常我们可以拿到TPS、响应时延等性能数据,那么如何定位性能问题呢? TPS、响应时延只能告诉你服务器是否存在问题,但不能帮助你定位问题。这些表面背后是整个后台处理逻辑综合作用的结果,这时候可以先关注系统的CPU、内存、IO、网络,对比在tps、时延达到瓶颈时这些系统数据的情况,确定性能问题是系统哪一部分造成的,然后再回到代码的逻辑中逐个优化这些点。 3)当服务器的整体性能就可以相对稳定下来,这时候就需要对自己服务器的承载能力有一个预估,通过产生真实压力、对比系统数据,大致可以对单套系统的处理能力有个真实的评价,然后结合业务规模配置服务器数量。
7. 参考文献 https://zhidao.baidu.com/question/498084507.html http://www.51testing.com/html/56/n-3723356.html https://blog.csdn.net/github_27109687/article/details/71968662 https://blog.csdn.net/zl1zl2zl3/article/details/78194194 8. 更多讨论 2.JMeter的使用步骤 (1)添加线程组 (2)添加http请求 (3)在http请求中写入接入url、路径、请求方式和参数 (4)添加查看结果树 (5)调用接口、查看返回值 3.压测任务需求的确认 压测前要明确压测功能和压测指标,一般需要确定的几个问题: 1. 固定接口参数进行压测还是进行接口参数随机化压测? 2. 要求支持多少并发数? 3. TPS(每秒钟处理事务数)目标多少?响应时间要达到多少? 4. 压服务器名称还是压服务器IP,一般都是压测指定的服务器 4.压测设置 1. 线程数:并发数量,能跑多少量。具体说是一次存在多少用户同时访问 2. Rame-Up Period(in seconds):表示JMeter每隔多少秒发动并发。理解成准备时长:设置虚拟用户数需要多长时间全部启动。如果线程数是20,准备时长为10,那么需要10秒钟启动20个数量,也就是每秒钟启动2个线程。 3. 循环次数:这个设置不会改变并发数,可以延长并发时间。总请求数=线程数*循环次数 4. 调度器:设置压测的启动时间、结束时间、持续时间和启动延迟时间。