并发模式与 RPS 模式之争,性能压测领域的星球大战

本文是《如何做好性能压测》系列专题分享的第四期,该专题将从性能压测的设计、实现、执行、监控、问题定位和分析、应用场景等多个纬度对性能压测的全过程进行拆解,以帮助大家构建完整的性能压测的理论体系,并提供有例可依的实战。

该系列专题分享由阿里巴巴 PTS 团队出品,欢迎在文末处加入性能压测交流群,参与该系列的线上分享。

第一期:《压测环境的设计和搭建》,点击这里。
第二期:《性能压测工具选型对比》,点击这里。
第三期:《阿里巴巴在开源压测工具 JMeter 上的实践和优化》,点击这里。

1996年, LR 4.0 版本发布,将性能测试专业理论工具化、产品化,这直接影响之后20多年性能测试领域的理论基础。但是 LR 作为一款商业化产品,因其价格昂贵,推广和传播受限。1998年底,JMeter 开源 ,并发布1.0版本,性能测试领域逐渐蓬勃发展起来。

Loadrunner、Jmeter 引领了性能测试领域的一个时代,功能强大,脚本化,扩展性强,将性能测试标准化、专业化,后续几乎所有性能测试工具或者商业化产品都马首是瞻。本文就性能测试做了一个纯YY的“实践”(真的只是纯理论分析!),有一些不一样的思路跟大家一起探讨下,望轻踩。

前言:并发、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》的文章,这两者是等价的。

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?(如下图)

在平衡状态下,我们从宏观的视角来分析下,整条流水线包装完一个箱子的 总耗时=(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)

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

  • 在平衡状态下,所有节点的 RPS 必然一样。
  • 在平衡状态下,任意节点的 RT 都会影响整体 RPS ,进而会影响并发在节点之间的分配关系。

为了描述方便,我们将节点A、节点B和节点C组成的“100人的流水线”叫做“串联链路”。

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

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

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

你确定考虑全面了吗?

控制并发是目前最为普遍被使用到的压测模式,打个比方,有一个网站大概会在 下周一10:00 预估有 10w人同时访问,那么为了保障网站的问题,很自然的想到使用10w个并发来压测下整个网站的接口,对应到 JMeter 即为设置线程组的线程数,对应到 LoadRunner 设置 VU(Visual User)数,很容易理解。

另外,我从阿里云PTS官方拿到近6个月的数据显示,选择并发模式与RPS模式分别占比 89%与11%,并发模式占据绝对的规模优势。

但是,如果你已经充分了解了“RT对于固定并发模式的性能测试的影响”,这里我不禁要问一句(邪恶脸)“Emm... 你有想过类似Jmeter、LR等并发模式压测工具拿到的结果是真实的吗?准确吗?”。

下面我要讲一个“恐怖故事”,先来看一张相对抽象的环境结构图,

在平衡状态下,已知总并发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 的因素实在是太多太多了,任何客观因素的影响都直接影响测试结果的准确性。

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

在这里,我更愿意定义并发模式性能测试为一种性能瓶颈分析的定性工具,在尽量相同的条件下经过反复测试,通过分析各个接口的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 都是一样的,与“实际情况”(图右部分)大相径庭。

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

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

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

数据显示,DevOps 第一次超过 Waterfall(瀑布模式)成为第二位被越来越多的企业接受的开发模式,而瀑布模式等传统开发模式有逐渐退出历史舞台的趋势。敏捷开发和 DevOps 大行其道,开发、测试和运维等部门、角色之间需要有一种高效的沟通和协作手段。

想到了一句非常“肤浅”但有点道理的话,“性能问题优化之后最终都可以转化为容量问题”,简单地可以理解为测试同学发现了性能瓶颈,然后开发同学经过了优化,运维同学根据优化之后的系统的能力进行扩容或者缩容。瞧!这不就是开发、测试和运维完美协作的一个典型实践嘛?!

这个过程,我们叫做“容量规划”的实施过程,重点不是容量而是规划,如果成本不是任何问题,我们可以堆砌无限大的资源,用户体验会极其好,但是会造成极大的资源浪费。所以这里说的“容量规划”是在保证用户体验不受影响(稳定性)的前提下,使有限的资源的利用率最大化(成本)的方法论。打个比方,运维准备了100台机器,有5个应用,那么“怎么分配这100台机器给5个应用可以使系统既可以正常对外服务又可以使系统达到最大的吞吐量能力”就是容量规划要解决的问题。

容量规划的核心有一张已经用的“泛黄”的图,大家应该一看就明白,有两个核心指标:

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

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

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

容量规划的目的性非常强,也就是在特定“流量模型”下,给出资源分配的最优解。在压测实施的时候,压测的主体是接口的 RPS,按照流量模型进行试压。(如果你还在想为什么主体是 RPS 而不是并发的话,请在仔细阅读前面那章)

RPS 模式压测在容量规划的典型应用,是并发模式无法实现的。正式因为此,我们才能将性能测试从“定性分析”转化为“定量分析”。

阿里在2013年构建了一整套基于线上全链路压测的容量规划体系,逐渐替代之前单应用、单接口这种低效的容量评估手段,过程也是非常曲折的。容量规划是一个非常大的课题,本文的重点不是“容量规划”,如果你对“智能化全链路容量规划”感兴趣,请在文末留言或加入我们的性能压测交流钉群。

结尾:无意引战

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

当然,我无意引战,并发模式、RPS 模式、你想要的和你还没有想到未来想要的都可以在 阿里云PTS 上找到。


原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/518351.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Akka in Schedulerx2.0

1. 前言 Schedulerx2.0是阿里中间件自研的基于akka架构的新一代分布式任务调度平台,提供定时、任务编排、分布式跑批等功能,具有高可靠、海量任务、秒级调度等能力。 本篇文章以Schedulerx2.0为例子,介绍akka的应用场景,希望能给…

java.sql.SQLException: The server time zone value ‘???ú±ê×??±??‘ is unrecognized or represents more

【报错信息】 【百度翻译】 服务器时区值???????无法识别或表示多个时区。如果要利用时区支持,必须配置服务器或JDBC驱动程序(通过ServerTimeZone配置属性),以使用更具体的时区值 【解决方法】 数据库连接配置conf.xml(…

【从入门到放弃-Java】并发编程-锁-synchronized

简介 上篇【从入门到放弃-Java】并发编程-线程安全中,我们了解到,可以通过加锁机制来保护共享对象,来实现线程安全。 synchronized是java提供的一种内置的锁机制。通过synchronized关键字同步代码块。线程在进入同步代码块之前会自动获得锁…

Redis 学习之一招击穿自己的系统,附送 N 个击穿解决大礼包 | 原力计划

作者 | Mark_MMXI来源 | CSDN博客,责编 | 夕颜出品 | CSDN(ID:CSDNnews)缓存的存在是为了在高并发情形下,缓解DB压力,提高业务系统体验。业务系统访问数据,先去缓存中进行查询,假如缓存存在数据…

阿里巴巴王坚:用数据来改变世界

“传统信息化建设都是从无到有,加了杆子和机器,但是新一代数字建设就是从有到无,缴费的机器没有了,你回家缴,杆子没有了,你回家缴。” 7月21日,阿里巴巴技术委员会主席王坚在2019年中国电子政务…

Knative Service 之流量灰度和版本管理

本篇主要介绍 Knative Serving 的流量灰度,通过一个 rest-api 的例子演示如何创建不同的 Revision、如何在不同的 Revision 之间按照流量比例灰度。 部署 rest-api v1 代码 测试之前我们需要写一段 rest-api 的代码,并且还要能够区分不同的版本。下面…

在生产环境中使用 Sentinel

文章目录一、安装zookeeper1. linux环境2. windows环境2. 安装并启动zkui二、编译打包2.1. 拉取项目2.2. 启动2.3. 登录 sentinel2.4. 登录zkui2.5. 重启Sentinel2.6. 删除Sentinel的流控规则三、将客户端和zk打通3.1. 引入依赖3.2. 配置3.3. 启动springboot3.4. sentinel控制台…

JavaScript-浏览器控制台使用

基本语法 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><!-- JavaScript 严格区分大小写 --><script>// 1. 定义变量 变量类型 变量名 变量值var num 1;num …

看完就入门系列!吞吐量、消息持久化、负载均衡和持久化、伸缩性…… 你真的了解 Kafka 了吗?...

作者| liuhehe123来源| CSDN博客 责编| Carol出品| CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;封图| CSDN下载于视觉中国 无论是已经接触过 Kafka 还是刚入坑的小伙伴&#xff0c;都应该时不时回头了解一下 Kafka &#xff0c;有时候会有不少新收获。今天这份…

Alibaba Cloud Linux 2 开源后又有什么新动作?

阿里妹导读&#xff1a;2019 年 4 月&#xff0c;Alibaba Cloud Linux 2 (Aliyun Linux 2) 正式开源。时至今日&#xff0c;已经走过三个月的里程。在这段时间内&#xff0c;这个刚诞生不久的为阿里云 ECS 环境定制优化的 Linux 操作系统发行版的装机量稳步上升。本文将重点介绍…

一站式数据采集存储的利器:阿里云InfluxDB®️数据采集服务

背景 随着时序数据的飞速增长&#xff0c;时序数据库不仅需要解决系统的稳定性和性能问题&#xff0c;还需实现数据从采集到分析的链路打通&#xff0c;才能让时序数据真正产生价值。在时序数据采集领域&#xff0c;一直缺少自动化的采集工具。虽然用户可以使用一些开源的采集…

Serverless 风起云涌,为什么阿里、微软、AWS 纷纷拥抱开源 OAM?

作者 | 张磊&#xff0c;阿里云原生应用平台高级技术专家邓洪超&#xff0c;阿里云技术专家责编 | 唐小引头图 | CSDN 下载自东方 IC出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;Serverless 这个词第一次被是 2012 年一篇名为《Why The Future of Software and …

K8S从懵圈到熟练 - 我们为什么会删除不了集群的命名空间?

阿里云售后技术团队的同学&#xff0c;每天都在处理各式各样千奇百怪的线上问题。常见的有&#xff0c;网络连接失败&#xff0c;服务器宕机&#xff0c;性能不达标&#xff0c;请求响应慢等。但如果要评选&#xff0c;什么问题看起来微不足道事实上却足以让人绞尽脑汁&#xf…

为什么技术人一定要懂点“可信计算”?

阿里妹导读&#xff1a;可信计算&#xff08;TrustedComputing&#xff0c;简称TC&#xff09;是一项由TCG(可信计算组)推动和开发的技术。可信的核心目标之一是保证系统和应用的完整性&#xff0c;从而确定系统或软件运行在设计目标期望的可信状态。可信和安全是相辅相成的&am…

很用心的为你写了 9 道 MySQL 面试题,建议收藏!

来源 | Java 建设者责编| Carol封图| CSDN下载于视觉中国 MySQL 也是作者本人正在学习的部分&#xff0c;后面会多输出 MySQL 的文章贡献给大家&#xff0c;毕竟 MySQL 涉及到数据存储、锁、磁盘寻道、分页等操作系统概念&#xff0c;而且互联网对 MySQL 的注重程度是不言而喻的…

OpenTelemetry-可观察性的新时代

有幸在2019KubeCon上海站听到Steve Flanders关于OpenTelemetry的演讲&#xff0c;之前Ops领域两个网红项目OpenTracing和OpenCensus终于走到了一起&#xff0c;可观察性统一的标准化已经扬帆起航。 这篇文章旨在抛砖引玉&#xff0c;希望能够和更多的同学一起交流可观察性相关的…

JavaScript-严格检查模式

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><!--前提&#xff1a; IDEA需要设置支持ES6 语法use strict; 必须写在JavaScript 的第一行严格检查模式&#xff0c;预防JavaS…

我们为什么需要 SpringBoot?

作者 | 阿文&#xff0c;责编 | 郭芮头图 | CSDN 下载自东方IC出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;任何先进技术的产生都不是凭空出现的&#xff0c;SpringBoot 也不例外&#xff0c;SpringBoot 是基于Spring 的基础上产生的。总所周知&#xff0c;Spri…

高德网络定位之“移动WiFi识别”

导读 随着时代的发展&#xff0c;近10年来位置产业蓬勃发展&#xff0c;定位能力逐渐从低精度走向高精度&#xff0c;从部分场景走向泛在定位。设备和场景的丰富&#xff0c;使得定位技术和能力也不断的优化更新。定位能力包括GNSS、DR&#xff08;航迹推算&#xff09;、MM&a…

JavaScript-字符串

字符串 正常字符串使用单引号 或者 双引号 包裹注意转义字符 \ \ \n \t \u4e2d \u#### Unicode字符 \x41 Ascll字符多行字符串编写 // tab 上面 esc下面的引号 let msg helloworld你好 console.log(msg)模板字符串 let name ht let age 5; let msg hello${name}你…