如何做好性能压测(二) | 施压方式选择(rps or 并发)-阿里云开发者社区

开发者社区> 阿里云SRE技术社区> 正文
登录阅读全文

如何做好性能压测(二) | 施压方式选择(rps or 并发)

简介: 如何做好性能压测(二) | 施压方式选择(rps or 并发)

image.png
image.png

题目:你正在做的性能测试不是你想象中的样子
1996年LR 4.0版本发布,将性能测试专业理论工具化、产品化,这也直接影响后20多年至今性能测试领域的理论基础。但是LR是一个商业化产品,价格昂贵,1998年底开源社区贡献Jmeter 1.0发布上线,性能测试逐渐蓬勃发展起来了。
Loadrunner、Jmeter引领了性能测试领域的一个时代,功能强大,脚本化,扩展性强,将性能测试标准化、专业化,后续几乎所有性能测试工具或者商业化产品都马首是瞻。本文就性能测试做了一个纯YY的“实践”(真的只是纯理论分析!),有一些不一样的思路跟大家一起探讨下,望轻踩。

1. 前言:并发、RPS和RT

接触性能测试的同学要理解的概念有非常多,在正文之前先跟大家就几个核心指标统一下口径:

  • 并发用户、并发、VU:一般用来表示虚拟用户(Virutal User,简称VU),对应到Jmeter的线程组线程,对应到Loadrunner的并发Concurrency,在本文都是一个意思。
  • 每秒发送请求数、RPS:指客户端每秒发出的请求数,有些地方也叫做QPS,本文不单独讨论“事务”所以可以近似对应到Loadrunner的TPS(Transaction Per Second, 每秒事务数),本文统一叫做RPS。
  • 响应时间、RT:对,没错,这个就是你理解的那个意思,从发起请求到完全接收到应答的时间消耗。

根据“Little定律”,在平衡状态下,我们可以等价认为并发、RPS和RT之间的关系可以概括为

并发数 = RPS * 响应时间

偷懒的话,可以把它当成性能测试领域的“乘法口诀”,直接背下来吧,他会帮助你快速理解很多问题;如果想深入了解具体的原理可以去拜读下Eric Man Wong 在2004年发表了名为《Method for Estimating the Number of Concurrent Users》的文章,这两者是等价的。

2. 100工人的问题

如果你还不了解“RT对于并发模式的性能测试的影响”或者还存在一些疑惑,强烈建议读完本章;如果不想理解细节,可以选择直接跳到本章末尾看结论;如果已经充分了解了,可以直接跳过本章。
先从一个大家相对熟知的例子开始,假设有这么一条生产箱子的流水线,安排了100个工人,条件如下:

  • 100个工人的身体素质一模一样, 因此可以近似的认为工作效率只与工作的复杂度有关;
  • 这个流水线有3份工作(如下图所示的节点A、节点B和节点C),所有工人都可以胜任;
  • 节点A工人包装箱子平均耗时 RT1=0.5s(秒),节点B工人包装箱子平均耗时 RT2=3s(秒),节点C工人包装箱子平均耗时 RT3=1.5s(秒)
  • 同一个箱子必须按照 节点A、节点B、节点C 的顺序被包装。

问:节点A、节点B、节点C分别安排多少工人 X、Y、Z 可以让这个流水线达到最大的产能,并且求得流水线的最大产能 T/s?如下图所示。

image.png

在平衡状态下,我们从宏观的视角来分析下,整条流水线包装完一个箱子的 总耗时=(0.5+3+1.5)s,那么我们可以很轻易地得到流水线的产能:

流水线的产能 T = 100 / (0.5 + 3 + 1.5) = 20 /s

可能很多人有疑问,“什么是平衡状态?”,这个可以这么理解,为了保证所有工人都可以达到最大的工作效率,主管会非常睿智的调配各个节点之间的工人分配直到“所有工人都有事可做,也不会存在工人忙不过来”,那么从微观的角度去看,如果节点之间的产能不一致,有些节点就会出现箱子等待被处理,有些节点的工人等待箱子的情况。所以,我们可以得到这样的结论 在平衡状态下,所有节点产能肯定是一致的:

T(A) = T(B) = T(C) = T = 20 /s

从而,根据little定律,我们可以推算出来,各个节点的人员(vu)分配了:

X = T(A) RT1 = 20 0.5 = 10

Y = T(B) RT2 = 20 3 = 60
Z = T(C) RT3 = 20 1.5 = 30

下面这张Jmeter的图,相信大家可以轻易地跟前面的自理找到对照关系,我这里不再赘述了:

产能 = RPS

工人 = 并发
完成平均时间RT = 响应时间、RT(rt)

image.png

综上所述,我们可以得出两个结论:

  • 在平衡状态下,所有节点的RPS必然一样
  • 在平衡状态下,任意节点的RT都会影响整体RPS,进而会影响并发在节点之间的分配关系。
为了描述方便,我们将节点A、节点B和节点C组成的“100人的流水线”叫做“串联链路”。

节点A的RPS = 节点B的RPS = ... = 串联链路RPS

串联链路RPS = 并发数 / (RT1 + RT2 + ... )

节点N的并发数 = RTn 节点N的RPS = RTn 串联链路RPS

3. 你确定考虑全面了吗?

控制并发是目前最为普遍被使用到的压测模式,打个比方,有一个网站大概会在 下周一10:00 预估有 10w人同时访问,那么为了保障网站的问题,很自然的想到使用10w个并发来压测下整个网站的接口,对应到JMeter即为设置线程组的线程数,对应到LoadRunner设置VU(Visual User)数,很容易理解。
另外,我从 阿里云PTS 官方拿到近6个月的数据显示,近10000+企业用户中,选择并发模式与RPS模式分别占比 89%与11%,并发模式占据绝对的规模优势。
但是,如果你已经充分了解了“RT对于固定并发模式的性能测试的影响”,这里我不禁要问一句“Emm... 你有想过类似Jmeter、LR等并发模式压测工具拿到的结果是真实的吗?准确吗?”。
下面我要讲一个“恐怖故事”,先来看一张相对抽象的环境结构图。

image.png

在平衡状态下,已知总并发VU,以及 接口1、接口2、接口3 的响应时间分别为RT1、RT2、RT3,通过前面的理论基础,我们可以轻易地写出下面的算式:
T = RPS1 = RPS2 = RPS3 = VU / (RT1 + RT2 + RT3)

接口1的并发 X = T * RT1

接口2的并发 Y = T * RT2
接口3的并发 Z = T * RT3

分析下接口的RT的构成,大致概括为下面5部分:

  • 压测工具耗时:这个很好理解,压测工具在发送请求之前会做参数的拼装/替换、下载应答报文、解析应答报文(断言)等都是需要耗费时间的,一般情况下压测工具的时间消耗会非常低,可以忽略。但是对于报文较大或者断言较复杂的情况下,压测工具耗时过大也会出现瓶颈;
  • 网络时间:一般来说在VPC/IDC内部的网络消耗非常低,所以我们可以近似地认为网络时间消耗都来源于运营商网络。同样,对于接口的请求和应答报文比较大的情况下,不论是运营商网络还是内网网络的带宽都更容易出现瓶颈;
  • 安全、鉴权、负载均衡模块耗时:这一块的时间消耗一般来说相对较低,受限于连接数、带宽等,可能会出现由于配置问题,比如连接数上限超过预期,则会造成等待建连超时;
  • 应用业务处理耗时:一般情况下,应用业务处理耗时占据RT的百分比最高,也是一般我们可以通过优化提高吞吐量的重点区域。可能包含 应用之间RPC服务调用、数据库SQL执行、读写缓存、读写消息等。
  • 第三方依赖耗时:这里就复杂了,各种情况都有,你可以完全信赖或者完全不信赖它的稳定性。一般它的RT评估有相关SLA的要求,一般压测实施的时候根据SLA约定的RT要求,mock掉第三方接口依赖,正式压测的时候再一起联压。

更进一步,可以得出这样的结论,在并发模式下,影响压测结果以及应用服务器的吞吐量的因素有:

  • 压测工具的性能
  • 网络状态
  • 接入层配置和性能
  • 应用服务性能
  • 第三方依赖的SLA

...

因此,出现了一种混沌状态,可能由于压测工具所在宿主机负载变化、网络环境变化、应用服务性能优化或者劣化等因素的干扰,拿着相同的脚本进行了10次,每次得到的接口RPS都不一样,服务器端的压力也不一样,但是从表象来看,一切正常,但这样的性能测试并不能真实反映任何问题,也并不能指导运维做出正确容量规划的决策。因为影响RT的因素实在是太多太多了,任何客观因素的影响都直接影响测试结果的准确性。

4. 并发模式=性能瓶颈“定性”分析

在这里,我更愿意定义并发模式性能测试为一种性能瓶颈分析的定性工具,在尽量相同的条件下经过反复测试,通过分析各个接口的RT构成找到“相对的”性能瓶颈。但是大家有没有想过,将所有接口优化到极限的性能之后,可以拍胸脯说“我们的系统已经可以抗住XXX并发用户量的访问了”吗?答案是否定的,原因有三:

  • 不真实,主要体现在 ① 环境不真实;② 压测(脚本)模型不真实;
  • 主体错误,并发只是一个诱因和触发器,影响性能的主体是服务端的RPS;
  • 并发测试的效果真实性依赖于RT,而RT的构成异常复杂。

对了,前面的分析漏了(我故意的)一个影响并发性能测试结果的非常重要的因素:思考时间(用户在操作的时候,步骤之间用户会停顿一段时间)。思考时间的引入会将并发的建模的复杂度带到几乎不能实现的地步,因为它不像其他相对客观的因素,它是非常主观的。假如用户停留的时间很长,可能是因为感兴趣多看一会儿,或者页面上有100个表单需要填写,或者看不懂文案是啥意思正在google,或者...去冲咖啡了。
有人可能会追问“思考时间究竟要设置多少合适呢?”,我可以非常明确的说“不知道!”,如果你有时间,可以通过大数据BI分析统计学意义上的每个接口之间用户停顿的时间,然后将它设置上,假设每个接口的思考时间总和为 S=(S1+S2+S3),那么我们可以更新下公式:

T = RPS1 = RPS2 = RPS3 = VU / (RT1 + RT2 + RT3 + S)

接口1的并发 X = T * RT1

接口2的并发 Y = T * RT2

接口3的并发 Z = T * RT3

可以看到,增加了思考时间之后,整体的吞吐量、所有接口的并发都下降了,因为有部分用户在“思考”。增加“思考时间”有助于提高并发模式下性能测试的准确性,除此之外,还有一些提高并发模式的准确性的手段:

  • 压测工具地域定制、运营商定制
  • 增加条件跳转,模拟用户重试行为
  • 增加集合点

...

这些手段你可以非常轻易的在市面上的开源或者云测平台上找到(有些功能可能需要支付一些费用),在这里不再一一赘述,归根到底,可以总结为“优化接口RT使其接近真实值以提高并发模式的准确性”。
但并发模式始终都受制于“不稳定的”、“难模拟的”、“难预测的”接口RT,通过并发模式拿到指导运维进行容量规划的结果,是要付出的代价会非常大的,甚至也不能达到想要的结果。
在真实情况下,接口1、接口2、接口3的RPS是不一样的,抛开接口异常断言失败不继续调用后面的接口的情况,接口RPS关系是呈倒金字塔分布,比方说,浏览商品(接口)了之后不一定会去下单购买(接口),因为大家一般会反复浏览不同的商品选择最中意的再下单,所以浏览商品(接口)的RPS必然会比下单购买(接口)的RPS要高,用户有放弃继续“走下一步”的权利,但是这种情况你如果尝试对并发的分布来建模,是一个非常庞大且复杂工程问题,因为影响的因素实在太多了。
如下图所示,并发压测模式下,所有接口的RPS都是一样的,与“实际情况”(图右部分)大相径庭。

image.png

受传统性能测试思路的影响,目前有 接近90%的企业用户(数据来源于阿里云PTS[1] ) 将并发模式性能测试的结果作为稳定性、容量验收的依据,所以说这是一件非常恐怖的事情。

5. 容量规划:从定性分析到定量分析

在这里我非常乐意跟大家分享一份来源于 QA Intelligence[2]《State of Testing™ Report 2019》关于2016~2019年软件开发模式的调查数据:

image.png

软件开发模式占比(2019、2018、2017、2016)
数据显示,DevOps第一次超过Waterfall(瀑布模式)成为第二位被越来越多的企业接受的开发模式,而瀑布模式等传统开发模式有逐渐退出历史舞台的趋势。敏捷开发和DevOps大行其道,开发、测试和运维等部门、角色之间需要有一种高效的沟通和协作手段。
想到了一句非常“肤浅”但有点道理的话,“性能问题优化之后最终都可以转化为容量问题”,简单地可以理解为测试同学发现了性能瓶颈,然后开发同学经过了优化,运维同学根据优化之后的系统的能力进行扩容或者缩容。瞧!这不就是开发、测试和运维完美协作的一个典型实践嘛?!
这个过程,我们叫做“容量规划”的实施过程,重点不是容量而是规划,如果成本不是任何问题,我们可以堆砌无限大的资源,用户体验会极其好,但是会造成极大的资源浪费。所以这里说的“容量规划”是在保证用户体验不受影响(稳定性)的前提下,使有限的资源的利用率最大化(成本)的方法论。打个比方,运维准备了100台机器,有5个应用,那么“怎么分配这100台机器给5个应用可以使系统既可以正常对外服务又可以使系统达到最大的吞吐量能力”就是容量规划要解决的问题。
容量规划的核心有一张已经用的“泛黄”的图,大家应该一看就明白,有两个核心指标:

  • 预估的业务量级:对于单应用而言就是这个应用的RPS吞吐量峰值,这个数据一般可以来源于流量模型和历史数据沉淀;
  • 单台机器的能力值:在某一个流量模型下,单台机器系统水位达到安全水位时的RPS峰值。

image.png

上面提到一个概念叫做“流量模型”,这个流量模型你可以近似的认为就是前面图中“实际情况”的RPS倒金字塔,他有两个要素,

  • 接口范围
  • 每个接口的RPS

容量规划的目的性非常强,也就是在特定“流量模型”下,给出资源分配的最优解。在压测实施的时候,压测的主体是接口的RPS,按照流量模型进行试压。(如果你还在想为什么主体是RPS而不是并发的话,请在仔细阅读前面那章)
RPS模式压测在容量规划的典型应用,是并发模式无法实现的。正式因为此,我们才能将性能测试从“定性分析”转化为“定量分析”。
阿里在2013年构建了一整套基于线上全链路压测的容量规划体系,逐渐替代之前单应用、单接口这种低效的容量评估手段,过程也是非常曲折的。容量规划是一个非常大的课题,本文的重点不是“容量规划”,如果你对“智能化全链路容量规划”感兴趣,请留言。

6. 结尾:无意引战

并发模式与RPS模式压测各有各自的使用场景,并发模式更加适用于对于系统定性的分析,比如帮助定位性能瓶颈,单接口的性能基线沉淀(对比历史性能优化or劣化);而RPS模式在对系统做定量的分析有杰出表现,比如容量规划,全链路性能基线沉淀,当然也可以帮助定位性能瓶颈。并发模式的难点在于RT的准确性拟真,RPS模式的难点在于模型的准确性评估和预测,从实现难度上来说,前者相对于后者来说难度更大一些、掌控度更低一些。
当然,我无意引战,并发模式、RPS模式、你想要的和你还没有想到未来想要的都可以在 阿里云PTS 上找到。
Done!

参考文档

[1] 阿里云PTS:https://www.aliyun.com/product/pts
[2] QA Intelligence:https://qablog.practitest.com/

相关内容

如何做好性能压测(一)丨压测环境设计和搭建

我们是阿里云智能全球技术服务-SRE团队,我们致力成为一个以技术为基础、面向服务、保障业务系统高可用的工程师团队;提供专业、体系化的SRE服务,帮助广大客户更好地使用云、基于云构建更加稳定可靠的业务系统,提升业务稳定性。我们期望能够分享更多帮助企业客户上云、用好云,让客户云上业务运行更加稳定可靠的技术,您可用钉钉扫描下方二维码,加入阿里云SRE技术学院钉钉圈子,和更多云上人交流关于云平台的那些事。

image.png

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:

阿里云智能全球技术服务部SRE团队,是阿里集团高可用基础技术核心缔造团队,也是阿里为确保客户平台稳定、业务连续而打造的核心支撑团队

官方博客
官网链接