【新手必读】关于压力测试不得不说的二三事
注:本文并不百分百是原创,参考资料已经列在文章最下方。
本文的目标读者
对压力测试一无所知、但需要了解比较系统的压测知识的新手人群。
本文大纲内容
- 压力测试相关的基础概念
- 常用压测工具的基本了解
- 了解压测的基本流程
相关的基础概念
软件测试的分类
软件测试如果按照是否查看代码分类,则可分为白盒测试、黑盒测试以及灰盒测试三类,其中黑盒测试又可分为功能测试与性能测试。我们这里主要探讨性能测试中的压力测试,而性能测试的具体分类如下:
- 基准测试:给系统施加较低压力,查看系统的运行状况并记录相关数据作为基础参考。
- 负载测试:对系统不断增加压力或增加在一定压力下的持续时间,直到系统的某项或多项性能指标达到安全临界值(例如某种资源已经达到饱和状态)。
- 压力测试:评估系统处于或超过预期负载时系统的运行情况,关注点在于系统在峰值负载或超出最大载荷情况下的处理能力。
- 稳定性测试:给系统加载一定业务压力,使系统运行一段时间,以此监测系统运行是否稳定。
- 并发测试:测试多个用户同时访问同一个应用、同一个模块或者数据记录时是否存在死锁或其它性能问题。
负载测试与压力测试的区别:
在负载测试中需要不断变化系统的负载,以测试系统在不同负载下的性能表现;在压力测试中则是让系统在极高的负载下测试系统的运行情况。
为什么要进行压力测试?
压测一般用于新系统上线支持、技术升级验证、业务峰值稳定性保障、站点容量规划以及性能瓶颈探测等。
- 新系统上线支持
在新系统上线前,通过执行性能压测能够对系统的负载能力有较为清晰的认知,从而结合预估的潜在用户数量保障系统上线后的用户体验。 - 技术升级验证
在系统重构过程中,通过性能压测验证对比,可以有效验证新技术的高效性,指导系统重构。 - 业务峰值稳定性保障
在业务峰值到来前,通过充分的性能压测,确保大促活动等峰值业务稳定性,保障峰值业务不受损。 - 站点容量规划
通过性能压测实现对站点精细化的容量规划,指导分布式系统机器资源分配。 - 性能瓶颈探测
通过性能压测探测系统中的性能瓶颈点,进行针对性优化,从而提升系统性能。
同时,压力测试也可以发现其他测试更难发现的错误,如内存泄漏、并发与同步。举个例子,2012年11月11日零点,阿里各种系统报错、立刻下单报错、购物车支付报错、支付系统报错、购物车的东西丢失,系统显示交易成功率不到50%,产生了大量超卖,给阿里带来很大的损失。这是因为错误预估了可能会达到的流量,没有明晰整个购物链路上每个系统的承受能力,也没有完善的预案,说明了压测的重要性。
压力测试的对象
我们可以对各种服务对象进行压力测试,例如接口、系统、后台服务等。
接口测试是测试系统组件间接口的测试,主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点;测试原理是通过测试程序模拟客户端向服务器发送请求报文,服务器接收并处理报文然后发送应答报文,客户端再接收服务器相应发出的应答报文这一过程。
实现接口测试的方法
- 使用接口测试工具:apipost、jmeter、loadrunner。
- 通过脚本进行接口测试,一般使用python编写脚本。
压力测试的特点
- 这种性能测试方法的主要目的是检查系统处于压力性能下时应用的表现。
- 这种性能测试一般通过模拟负载等方法,使得系统的资源使用达到较高的水平。
- 这种性能测试方法一般用于测试系统的稳定性。 也就是说,这种测试是让系统处在很大强度的压力之下,看系统是否稳定,哪里会出问题。
压力测试的作用
- 如果是新服务,无预估目标,则需要通过压测得到服务基准数据,或找到系统瓶颈进行优化;
- 如果有明确的压测目标,则需要通过压测确定服务的各项指标是否达标;
- 如果是常态化压测,则为后期性能优化指导方向或者提供参考依据。
压力测试的类型
-
单机压力测试
-
分布式压力测试
一般当需要测试大量并发,一台机器满足不了需求时会采用分布式压力测试。通俗解释就是由一台中控机(master)去调度其他多台机器(slave)执行对目标对象(target)的测试脚本,然后返回测试结果给中控机(master)。
压测常用的性能指标
-
每秒处理事务(TPS,Transaction Per Second)每秒系统处理事务(通过、失败以及停止)的数量。通过它可以确定系统在任何给定时刻的时间事务负载。
-
每秒查询率(QPS,Queries Per Second)一台服务器每秒能够响应的查询次数。通过它可以确定系统的最大吞吐能力。
-
并发用户数(Number of Concurrent Users)同一时间点请求服务器的用户数。
- 最佳并发用户数(The Optimum Number of Concurrent Users)随着并发量的增加,吞吐量(每秒处理事务)不再相应增加,并且响应时间继续增长。
-
事务平均响应时间(Average Transaction Response Time) 每一事务执行所用的平均时间,通过它可以分析测试场景运行期间应用系统的性能走向。
-
最大响应时间(Max Response Time) 指用户发出请求或者指令到系统做出反应(响应)的最大时间。
-
最少响应时间(Mininum ResponseTime) 指用户发出请求或者指令到系统做出反应(响应)的最少时间。
-
90%响应时间(90% Response Time) 是指所有用户的响应时间进行排序,第90%的响应时间。
-
-
CPU(CentralProcessing Unit) 中央处理器,是计算机的重要设备之一。功能主要是解释计算机指令以及处理计算机软件中的数据。
- CPU利用率(CPU Usage) CPU利用率分为用户态,系统态和空闲态,分别表示CPU处于用户态执行的时间,系统内核执行的时间,和空闲系统进程执行的时间。平时所说的CPU利用率是指:CPU执行非系统空闲进程的时间/CPU总的执行时间。
-
内存(Memory) 也被称为内存储器,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。
- 内存使用率(Memory usage) 内存占用率指的是此进程所开销的内存。
-
磁盘IO(Disk input/ output) 磁盘的读写包速率。
-
网卡负载(Network Load) 网卡的进出带宽,包量。
压测工具介绍
-
ab
ab(Apache Benchmark)是Apache公司提供的一款简单易上手的测试工具,一般用于测试web服务。它是一个命令行工具,对发起负载的本机要求很低,不会占用很多CPU或内存,但是会可能给目标服务器造成巨大的负载,其原理类似于
CC攻击
。它适用于本地对支持HTTP协议的单一地址进行性能压测。CC攻击(Challenge Collapsar)是针对web服务器或应用程序的攻击。原理是通过代理服务器或者大量肉鸡模拟多个用户访问目标网站的动态页面,制造大量的后台数据库查询动作,消耗目标CPU资源,造成拒绝服务。CC攻击的请求本身是正常的请求。
它可以根据命令创建很多并发访问线程,模拟多个访问者同时对某一个URL地址进行访问,以此测试目标服务器的负载压力。
它的扩展性比较低,用来测试post get接口请求非常便捷,但只能提供基本性能指标,没有图形化结果,无法监控。
-
LoadRunner
LoadRunner是HP公司提供的一款预测系统行为和性能的工业标准级测试工具,通过模拟成千上万个用户实施并发操作,测试系统的性能,并且提供详细的测试结果分析,协助用户查找问题。
它的工作原理是用虚拟用户脚本生成器用代理方式接收客户端发送的数据包进行处理并转发给服务器端,再接收从服务器端返回的数据流进行处理并返回客户端,通过这种方式来模拟真实运行环境;在整个过程中实时监控采集控制台上的所有资源并捕获性能数据,最后将结果存储在数据库的储存库中。
它基本包括了JMeter的常用功能,支持IP欺骗,优点是专业、稳定、高效,缺点是非开源免费,售价高,扩展性比较差。
IP欺骗是指利用带有假的源IP地址的IP协议分组来冒充另一个计算机系统身份,使发送方可以保持匿名的技术。在压力测试中,如果某一个IP访问过于频繁或者访问量过大时,服务器会拒绝访问请求,此时可以通过IP欺骗增加访问频率和访问量;还有某些服务器配置了负载均衡,使用同一个IP无法测出系统的实际性能;又或是一些网站会限制IP登录等等,为了真实模拟现实情况,都需要用到IP欺骗。
-
JMeter
JMeter是Apache公司组织开发的基于Java的测试工具,最初被设计用于web应用测试,但后来扩展到了其他测试领域。它的功能与LoadRunner比较相似,工作原理也基本一致——JMeter通过线程组来模拟真实用户对服务器的访问压力,可以作为服务器与客户端之间的代理网关以捕获请求和响应。另外,JMeter能够对应用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。为了最大限度的灵活性,JMeter允许使用正则表达式创建断言。
它是一款开源的免费软件,具有强大的开源社区支持,社区内开发者活跃程度高。它使用了图形界面,用户可以通过图形界面来编写测试用例,操作简单易上手;并且它体积小巧,不需要安装即可使用。
它相比于LoadRunner的缺点是结果分析能力没有LR强,且不支持IP欺骗。并且JMeter的性能不太稳定,在高并发下观测结果集时容易遭成界面卡死或崩溃。
这里只比较详细地介绍了三种最常见的压测工具,还有一些其他工具简单介绍如下:
- wrk:一款热门的HTTP性能测试工具,不支持Windows,支持大多数UNIX系统。只能单机测试,但是支持多线程,且可以在有限的资源下并发出极致的的负载请求。
- hey:一款基于golang的类似于ab的轻量级压测工具,只支持http接口的压力测试。
- k6:一种高性能的开源测试工具,可用于负载测试和性能监控。用户可使用JavaScript编写脚本。对开发人员友好,同时官方文档丰富 ,社区活跃。
- locust:一款基于python的分布式压力测试工具,提供UI界面,一般用于网站压力测试。由于采用了协程(gevent,一种轻量级线程)机制,所以单机并发能力很强,且比 jmeter更加轻量化。
- vegeta:一个基于golang的多功能的 HTTP 负载测试工具。它会以延时最小的方式尽可能少地建立并发连接数,所以不适合测试固定并发数下的QPS;但是它会尽全力满足你所设定的QPS,所以它是一款以压测QPS为主的工具。支持使用图表插件展示实时压测报告。
压测的基本流程
-
制定压测目标
可以通过历史监控数据(已经上线的服务,存在历史数据),类比(新服务/线上未监控的服务,但存在类似功能服务的历史数据)或者估算(不存在历史数据、不存在类似功能服务数据,使用
8/2原则
)去预估压测中期望服务能达到的性能预期。8/2原则:指一天内80%的请求会在20%的时间内到达。
-
场景配置
在压测前应明确需要压测的场景是什么,应有压测的优先级,高优先级场景有:
-
高频业务场景(今日头条首页下拉刷新)
-
关键业务场景,使用频率低,一旦出问题就很严重(微信账号登录)
-
性能高消耗场景(淘宝下单)
-
曾经出现过问题的场景
梳理完场景后,确认压测哪些服务,可能还需要对链路上相关的业务进行改造等。
-
-
准备压测环境
部署压测环境,需要模拟用户(业务)与系统的交互。常见的方法是使用线上环境压测,在负载低的时间段发起压测。
-
压测执行
前期工作是根据场景设计或者文本用例编写测试脚本以及对脚本进行调优等。在压测过程中一般从细粒度开始慢慢集成到整个大系统,如
单接口单机->单接口1/4资源->场景化1/4资源->全量资源压测->拨测
。单接口单机
在单核(或物理资源少)机器上部署单个服务,排除外部链路、网络等因素,得出自身服务的单核性能情况(单位QPS/core),后续根据此单核性能指标结合压测目标值进行扩容。另外由于是压的单接口单机,无其他接口请求影响,上下游在足够资源的情况下也不会造成瓶颈,所以能确保服务的性能真实值。
单接口单机可以在正式开始大规模压测前提前发现问题,方便RD做针对的性能优化并快速检验优化效果。一部分问题会先在单接口单机压测环节中发现,而一些隐藏得更深的问题,需要延后到全链路大流量压测才能暴露。
单接口1/4资源
单接口单机压测环节,服务端已经完成了部分性能优化,接下来可以进入单接口1/4资源压测,这样是为了验证在单接口单机压测中得到的单核性能数据,在扩容1/4资源下性能是否会线性增长,是否存在性能损耗以及定位损耗源。
场景化1/4资源
单接口压测局限很明显,场景化压测由于引入了上下游服务的其他接口的因素,可以发现单接口压测无法发现的问题,更接近线上用户场景。
全量资源全链路
全部资源到位后,预估的线上压力是否能承受,这一步也是内网压测过程的最后一步。
拨测
除了做内网压测,还要进行拨测验证用户从客户端到服务端的整个带宽资源是否满足预期,内网压测已经确认了业务性能是否达标,因此拨测可以只选择了一个场景进行验证即可。(简单来说拨测相当于压测cdn,检查各地cdn节点资源是否充足)
来源:服务端压测怎么做
-
压测监控分析
确认监控体系是否完整,对服务器、系统的资源指标和系统指标进行监控,一般监控项有:压测常用的性能指标指标。
-
报告总结
压测最终应该输出一份报告总结,其实也就是把整个压测方案、过程、结论记录下来,写明压测目标、压测接口、压测数据、压测结论,给出发现的问题并提供优化方案。往往在压测报告完成时,性能问题已经基本被解决了,报告的意义在于梳理前面的整个流程,给后续的压测提供经验指导。