03-揭秘大厂性能方案的奥秘!

性能方案在性能项目中是重要文档之一,它指导整个项目的执行过程,也约束项目边界,定义相关人员职能。但如今变得“微不足道”。

很多常见的性能项目中,性能方案就是个文档,且是个静态文档。里面写的东西是啥,项目后续会不会按这内容做,没人关心。它就成了形式,只有评审方案时才拿出看看。甚至一些第三方测试项目中,有些甲方连方案内容都不看,直接问有没有?有,就过去了。一个必需的交付物无人关心。

性能方案是个重量级文档。性能项目中被叫成“性能测试方案”。在我这,我把“测试”二字拿掉,因为这取决于我性能工程理念,我希望把整个项目的过程都描述在方案。

0 我的性能方案 V.S 那些常见性能方案

经常看到有这样目录的性能测试方案:

这样的目录大纲组成

  • 常规项目信息:如测试背景、测试范围、测试准则、测试环境、实施准备、组织结构、项目风险、里程碑。
  • 性能实施信息:如测试模型、测试策略、监控策略。
  • 项目输出:如测试脚本、测试用例/测试场景、监控采集数据,测试报告、调优报告。

从性能测试方案的角度来说,这些内容似乎够。但若抛弃“测试”视角,从一个完整的性能项目的角度来看,这些内容还不够。

以前经常有人问我要一个性能项目方案模板,我一直不理解,就这么一个目录,为什么还非得要?自己一个字一个字也照样写得出来吧。后来我慢慢理解,他们要的其实不是大纲目录,而是一个完整的性能方案内容。

项目实施的性能方案基本不可能直接发出来,即便脱敏,一些内容也可以看出是属于某些企业。所以网上看不到完整的性能方案。尽管网上方案不完整,在性能市场上,还是看到有太多性能方案抄来抄去,总体结构大同小异。这也就导致性能项目中,大量方案都只流于形式。

因为我们需要基于一个完整的项目来编写,所以,我把这个项目整体的方案写在这里。你将看到,我认为的真正完整并且有意义的性能方案是啥样。

由于性能方案的内容比较多,并且相对琐碎,整理了一张性能方案的目录表格,你可以对应这张表格,学习具体内容。

来看真实的性能项目实施方案:

1 背景

1.1 项目背景

由于各企业的商业软件有限制,只能选择一个开源项目,并且这个项目最好可以覆盖常见的技术栈,以便能给你提供更多可借鉴内容。因此搭建了一套电商项目:

  • 这个项目是较为完整的
  • 当前电商的系统比较典型,并且这个项目完全开源,便于改造

不过,也因为这是一个开源的项目,功能和性能都不知道会有什么样的问题,我们只有在性能实施的过程中一步步去发掘,所以这是一个非常符合我们当前目标的项目。

1.2 性能目标

  1. 根据经典的电商下单流程,测试当前系统的单接口最大容量。
  2. 根据业务比例设计容量场景,充分利用当前资源,找到当前系统的性能瓶颈,并优化,以达到系统的最佳运行状态。
  3. 根据稳定性场景,判断当前系统可支持的系统最大累加容量。
  4. 根据异常场景,判断当前系统中的异常对性能产生的影响。

在每一个性能项目中,性能目标都会影响项目的整个过程。因此,对目标的把握将决定一个性能项目的走向。

某项目,客户要求做到支持1000万人在线,项目不算小,开发团队有300人左右。到那一看只有两个性能测试人员,其中一个还刚毕业。于是,我就过去找他们科技部老大,说这项目我做不了。因为根据这个目标和这样的人员配置,这坑不是我能填上的,得赶紧认怂。后来,那个科技部的老大问,需要什么样资源才能做下去?于是我提几个必需条件,直到这些条件都满足,才接这项目。

性能目标在上下级眼中根本不一样,而我这样的处理,是希望把性能目标在上下级的脑袋中变得一致。这很重要。

2 测试范围

2.1 需要测试的特性

电商主流程:

img

2.2 不需要测试的特性

批量业务。

3 准则

3.1 启动准则

  1. 确定系统逻辑架构和部署架构和生产一致。
  2. 确定基础数据和生产一致或按模型缩放。
  3. 确定业务模型可以模拟生产真实业务。
  4. 环境准备完毕,包括:
    4.1. 功能验证通过。
    4.2. 各组件基础参数梳理并配置正确。
    4.3. 压力机到位,并部署完毕。
    4.4. 网络配置正确,连接通畅,可以满足压力测试需求。
  5. 测试计划、方案评审完毕。
  6. 架构组、运维组、开发组、测试组及相关专家人员到位。

3.2 结束准则

  1. 达到项目要求的性能需求指标。
  2. 关键性能瓶颈已解决。
  3. 完成性能测试报告和性能调优报告。

3.3 暂停/再启动准则

1. 暂停准则
  • 系统环境变化:举例:系统主机硬件损坏、网络传输时间超长、压力发生器出现损坏、系统主机因别的原因需升级暂停等。
  • 测试环境受到干扰,比如服务器被临时征用,或服务器的其他使用会对测试结果造成干扰。
  • 需要调整测试环境资源,如操作系统、数据库参数等。
  • 该测试机型无法达到规划指标要求。
  • 出现测试风险中列出的问题。

2. 再启动准则

  • 测试中发现问题得以解决。
  • 测试环境恢复正常。
  • 测试风险中出现的问题已解决。
  • 环境调整完毕。

4 业务模型和性能指标

4.1 业务模型/测试模型

img

这个模型是直接从生产环境中取得的业务比例,通过统计日志就能做到。

有些企业的生产数据都在运维手里,性能团队怎么也得不到,因为没有权限,就连做业务模型的数据都没有。那性能项目可直接终止,因为做了也没多大意义,最多也就是找那些瞎吹牛的架构师和乱写代码的开发人员,犯的一些错而已。

业务模型一般还可以由项目组提供生产上的业务报表,根据业务报表查看业务频繁的交易进行按比例,设计测试模型

业务指标/性能指标

在不清楚项目目标TPS的情况下,我暂定目标TPS为1000。根据经验来说,在这样的硬件环境下,定为1000并不算高,除非是没有合理的软件架构。

5 系统架构图

架构图的重要性:方便测试人员根据架构判断是否存在隐患及问题排除

5.1 系统技术栈

系统技术栈是让我们知道整个架构中用了哪些技术组件。而这些技术组件中有哪些常见的性能瓶颈点,有哪些性能参数,我们都可以在查看技术栈时得到一些相关信息。而在后续的工作中,我们也要整理出相应的关键性能参数配置。

下面这张表格,就是我们在后续案例分析中,会用到的技术栈。我在搭建这个系统时,考虑的是尽量覆盖当前技术市场中的主流技术组件。

5.2 系统逻辑架构图

为后续性能分析的时候,脑子里能有一个业务路径。做性能分析时,要做响应时间的拆分,只有了解逻辑架构图才知道从哪拆到哪。

5.3 系统部署架构图

画部署架构图是为让我们知道有多少节点、多少机器。在执行容量场景时,要有概念,这样的部署架构最大应该可以支持多少的容量上限。

对一些无理的性能需求,你看了部署架构后,就可拒绝。比如说前段时间有个人跟我说,他们有一个CRM系统,在做性能的时候,说要达到1万的并发用户。而实际上,那个系统就算是上线了,总用户数可能都不到1万。

img

系统部署架构图是不是就是系统各个层用了那些东西,这些是不是都要知道?是的。就是要知道各个层面用了哪些技术组件。同时还要知道业务路径是从哪里到哪里。

根据系统部署架构图,咋就能知道支持多少容量上限?有啥评判方法吗?这个问题,动手实践即知道。对你测试的系统,验证单节点的容量上限是多少,就能大概判断整个架构能支持多少,当然这过程中要有模型的创建过程。如在一个2C 4G机器,我直接用一个post接口做一个insert动作,在我的经验中,大概就是在500-600TPS左右。

6 性能实施前提条件

6.1 硬件环境

通过对整体硬件资源的整理,根据经验知道容量大概能支持多少的业务量级,而不至于随便定无理的指标。

如当看到下面表格中这样的硬件配置,没有人会把指标定为10000TPS。因为即使是对于最基础的接口层来说,这样的硬件也支持不了这么大的TPS。

img

当前服务器总共使用在应用中的资源是:64C的CPU资源,128G的内存资源。NFS服务器不用在应用中,故不计算在内。因为单台机器的硬件资源相对较多,所以在后续的工作中,我们可以将这些物理机化为虚拟机使用,以方便应用的管理。

在成本上,所有物理机加在一起大概8万左右的费用,这其中还包括交换机、机柜、网线等各类杂七杂八的费用。

对硬件的成本进行一个说明,主要是因为在当前的性能行业中,很少有性能工程师做成本计算。性能项目的目标是让线上的系统运行得更好,也要知道使用了多少成本在运行业务系统。

在当前的性能行业中,有大量的线上主机处于高成本低使用率的状态当中,这是极大资源浪费和成本消耗。经常在性能项目看到一台256C512G的硬件服务器里,只运行个4G JVM的Tomcat,性能工程的价值完全没有在这样的项目中应用。因此,我时常会痛心疾首地感慨性能行业不景气:

  • 企业中没有意识到性能的价值,觉得摆个高配置的硬件服务器,业务系统的性能就能好起来
  • 性能市场从业人员完全没有把性能的价值,透明化地体现出来。并且很多性能人员自身的技术能力不足,这也让一个企业完全看不到性能本该有的价值

鉴于此,作为性能从业人员,我们必须要了解硬件配置和整体业务容量之间的关系。

6.2 工具准备

6.2.1 测试工具

在测试过程中,我们将使用JMeter的backend Listener把数据直接发到InfluxDB中,然后再由Grafana来展现。我们不使用JMeter的分布式执行功能或本地收集数据的功能,因为这样会消耗本地的IO。

然而,现在还是有很多性能人员,仍然在项目中频繁地使用那些性能工具的低性能操作手段,同时还在不断抱怨性能这么差。理智使用工具,不要觉得一个性能测试工具拿起来就可以用。

6.2.2 监控工具

img

根据RESAR性能工程中的全局-定向的监控思路,我们在选择第一层监控工具时,要采集全量的全局计数器,采集的计数器包括各个层级,这里请参考前面的架构图。

但是,请你注意,在全局监控中,我们要尽量避免使用定向的监控手段,比如说java应用中的方法级监控、数据库中的SQL监控等。因为在项目开始之初,我们不能确定到底在哪个层面会出现问题,所以不适合使用定向监控思路。

那全局监控怎么来做才最合理呢?这里我们可以参考线上运维的监控手段。注意,我们在性能监控过程中,尽量不要自己臆想,随意搭建监控工具。

有时我们可能为了能监控得更多,会在测试环境中用很多监控手段。但实际上,线上运维时并不用那些手段,这就导致了监控对资源的消耗大于生产环境的资源消耗,我们也就得不到正常有效的结果。

前面我们提到在选择第一层监控工具时,需要采集全量的全局计数器。在我们采集好全局的计数器后,还需要分析并发现性能问题,然后再通过查找证据链的思路,来找性能瓶颈的根本原因。

6.3 数据准备

6.3.1 基础数据

img

在性能工程中,基础数据要满足:

  1. 满足生产环境的真实数据分布:最合理方式是脱敏生产数据。如果你要自己造数据的话,也一定要先分析业务逻辑。在我们这个系统中,我造了243万条用户数据和250万条地址数据。
  2. 参数化数据一定要使用基础数据来覆盖真实用户:很多人都在使用少量数据做大压力,这种逻辑完全不对。比如用同样的请求body去压测某个接口吗?为什么完全不对?请求在不同的用户下参数是不同的,如果用同样的参数去做压力,对后端的压力是不同的。在性能脚本中一定要用基础数据来做参数化,而用多少数据取决于性能场景的设计。参数化数据就是压力工具中用来做参数化的数据,这些数据有些是用户主动输入的,有些是要和后台DB对应。

7 性能设计

7.1 场景执行策略

7.1.1 场景递增策略

性能场景须满足:

  • 连续
  • 递增

不连续递增能咋样?如下图:

红框就是递增带来的性能问题表现。因为在递增过程中,被测系统的资源要动态分配。系统会不会在这个时候抖动,完全可以从这样的图中看出来,而这样的场景才是真实的线上场景。

若不连续递增,就不会有图中红框这样的部分。要是不连续递增,也就不能模拟出线上真实场景。

**要模拟生产场景,连续递增一定要做到的,不容迟疑。**而不同工具,设置连续递增的方式不同。

LoadRunner设计:

JMeter设计如下:

设计场景中,一定要做到上面这种连续递增的样子。

7.1.2 业务场景

在RESAR性能工程中,性能场景只需要这四类即可:

执行顺序先后为:基准场景、容量场景、稳定性场景、异常场景。

除这四类性能场景外,再没有其他类型场景。在每一个场景分类中,都可设计多个具体场景覆盖完整业务。

① 基准场景

用脚本加上三五个线程跑上多少次迭代,就算基准场景。这场景意义何在?它仅能验证一下脚本和场景是正确的。所以,我不把这样的步骤称为基准场景。

RESAR性能工程理念中,基准场景须是容量场景的前奏

具体怎么做?在基准场景中,也通过递增连续的场景做到最大TPS。即要把单接口或单业务压到最大TPS,然后分析单接口或单业务的瓶颈点。

基准场景中有必要做调优动作?应先判断当前单接口或单业务的最大TPS,有无超过目标TPS:

  • 超过,并且响应时间也在业务可接受的范围之内,不用调优
  • 没有超过,须调优

另外,根据RESAR性能工程理论,性能执行的第一阶段目标就是把资源用光,第二阶段的目标是将系统优化到满足业务容量。任一系统要调优都是无止境,而目标是要保证系统正常运行。

我们先做接口级的,然后把接口拼装成完整的业务量,并实现业务模型,然后再在容量场景中执行。我们将执行测试范围中接口的基准场景。

基准场景,混合场景的线程数怎么确定?递增连续的方式不需要确定压力工具中的线程数。只要确定业务比例就可以了。最大的线程数可能通过二分法确定。

二分法确定线程数

先根据资源和自己的经验判断一个系统的最大上限TPS,然后根据单线程的TPS,来计算需要多少线程。
若一个系统通过资源和经验判断出大概能达到1000TPS,而单线程的TPS是100,那大概能判断出需要10个线程就够了。这时直接上10个压力线程递增加压,看下。若把资源用完了或者有了瓶颈,这时就能分析优化。
如果没有用完或者出现瓶颈,那就直接上20个压力线程递增再来判断。
如果资源用得过多或者瓶颈有多个,那就可以降到5个线程再来判断。
依此类推。

基准测试中,连续递增50个线程数达到最大TPS,还有没有必要继续加线程数吗?到达多少线程数才不加?(需求没有线程数的要求)看你的目标是什么。如果是想达到系统最大TPS,对于容量场景来说那就没必要加了,要是系统还有问题,想把响应时间拖长一点以便分析,就可以再加。

业务有11个,要怎么组合这11个业务进行基准场景的测试?基准场景是拿单业务跑的,不用组合。

② 容量场景

有了基准场景的结果之后,进入容量场景的阶段。秉承“连续、递增”的执行思路,要实现业务模型,来真实模拟线上的业务场景。

  • 很多的性能项目里,大部分性能需求都提得不是很具体,从而导致性能场景的模型和生产场景不一致
  • 即便业务模型和生产一致了,也会由于性能工程师在执行过程中没有严格模拟业务模型中的比例,性能场景的结果变得毫无意义。执行过程中,响应时间会随着压力的增加而增加,仅用线程数来控制比例很不理智,因为在执行的过程中会出现业务比例失衡

如何控制这比例关系?JMeter的话,可用Throughput Controller控制业务比例:

img

总之,场景执行结束后,要把业务比例做统计,并且要和业务比例对比,当比例一致时,才算合理场景。

什么是最大TPS?看图,你觉得最大TPS多少?

img

**容量场景的最大TPS是指最大的稳定TPS。**你看,上面这张图已经抖动了,已经不稳定了,再去找它的最大TPS还有什么意义?你敢让一个生产系统运行在这样抖动的状态中?所以,对于上图中这样的TPS曲线,我会把最大的稳定TPS定为第三个阶梯,即600左右,而不定在700。

性能场景中,特别是在容量场景中,经常有人提到“性能拐点”,并且把性能拐点称作是判断性能瓶颈的关键知识。

拐点,又称反曲点,在数学上指改变曲线向上或向下方向的点。直观地说,拐点是使切线穿越曲线的点(即连续曲线的凹弧与凸弧的分界点)。

那么在TPS曲线中,你真的能找到这样的点吗?反正我找不到。就以我们上面那张图为例,图中哪里是拐点?也许有人会说这个曲线没有拐点。可见,性能拐点其实是一个在具体执行过程中非常有误导性的概念。请你以后尽量不要再用“性能拐点”这个词来尝试描述性能的曲线,除非你真看到拐点。

③ 稳定性场景

性能市场中,还没人给出稳定性场景应运行多长时间的确切结论。根据业务属性不同,稳定性场景也有不同设计思路。

稳定性场景中,只有两个关键点:

第一个关键点:稳定性场景的时长。

一个系统上线之后,运维人员肯定运维巡检,发现有问题就处理:

  • 有的系统是有固定的运维周期,比如说会设定固定的Job来做归档之类的动作
  • 有的系统是根据巡检的结果做相应的动作

稳定性要做的就是保证在运维周期之内业务能正常。 所以,在性能的稳定性场景中,要完全覆盖业务容量。

如下图:

运维周期内,有1亿笔业务容量。根据上面容量场景中的测试结果,假设最大稳定TPS 500,稳定性场景的执行时长就是:

稳定性时长 = 100000000 ÷ 500 ÷ 3600 ÷ 24 ≈ 2.3 ( 天 ) 稳定性时长 = 100000000 \div 500 \div 3600 \div 24 \approx 2.3 (天) 稳定性时长=100000000÷500÷3600÷242.3()

通过这样的计算,就能知道稳定性场景应跑多久,这也是唯一合理方式。

第二个关键点:用多大TPS执行。

有人说用最大TPS的80%来运行稳定性场景。why?凭啥不用最大的来运行?有人说之所以用最大TPS 80%,是因为在执行稳定性场景时不能给系统太大压力,否则易导致系统问题。这说法就怪了。既然容量场景都能得出最大TPS,为什么稳定性就不能用?若用最大的TPS执行稳定性场景会出现问题,那这些问题不正是我们希望测试出来的性能问题吗?为什么要用低TPS来避免性能问题的出现?所以,用最大TPS 80%做稳定性场景是错误思路。

执行稳定性场景时,完全可以用最大的稳定TPS来运行,只要覆盖了运维周期之内的业务容量即可。若你不用最大的稳定TPS来运行,而是用低TPS来运行,也必须要覆盖运维周期之内的业务容量。

④ 异常场景

对于异常场景,有些企业是把它放到非功能场景分类中的,这个我倒觉得无所谓。不管放在哪里都是要有人执行的。我之所以把异常场景放在性能部分,是因为这些异常场景需要在有压力的情况下执行。

对于常规的异常场景,我们经常做的就是:

  • 宕主机
  • 宕网卡
  • 宕应用

除此之外,在现在微服务盛行的时代,还有新招——宕容器。也可用一些所谓的“混沌工程“工具实现对容器的随机删除、网络丢包、模拟CPU高等操作。

性能方案中四种场景中需要添加各场景的性能用例吗?是的,要设计具体的每个类型下有多少要执行的性能场景。一般我不用“用例”这个词,因为这个词过小了。

7.2 监控设计

7.2.1 全局监控

有前面监控工具部分,监控设计就已出现在写方案人的脑里。系统全局监控:

img

使用Prometheus/Grafana/Spring Boot Admin/SkyWalking/Weave Scope/ELK/EFK就可以实现具有全局视角的第一层监控。对工具中没有覆盖的第一层计数器,只能在执行场景时再执行命令补充。

7.2.2 定向监控

在有问题时才使用:

img

性能分析中,除表格中的这三工具,还有很多工具在查找性能瓶颈证据链时使用,这里无法全部罗列,只能根据系统使用到的技术组件,罗列常用工具。

8 项目组织架构

性能方案一定要画出项目的组织架构图,写明各组织人员的工作范围和职责,避免扯皮。常见组织架构:

这是按事划分,而非职场的工作职位:

  • 性能脚本工程师所负责其实是现在大部分性能从业人员都在做且仅在做的。性能分析工程师在很多性能项目中几乎无,也没这样的固定职位。其实,性能分析工程师很有必要存在
  • 架构师、开发、运维都要在支持性能分析的状态。“支持”不是指站在旁边看,而是在有问题后,具体给出支持,而非推诿
  • 业务方,性能的业务需求来源,一定要有。若业务方提不出合理的性能需求,这项目基本稀碎
  • 老板,在性能项目中,经常看到老板都不懂啥是性能,只会叫着要支持XXX并发用户数,支持XXX在线用户数。这样的老板沟通起来也简单,拿结果给他。性能项目的执行过程中,当资源不足时,要让老板知道,同时降低老板预期,要不然在后续沟通很费劲

9 成果输出

9.1 过程性输出

  1. 脚本
  2. 场景执行结果
  3. 监控结果
  4. 问题记录

性能项目中有这些内容就够,不用更多,也不能更少。很多性能项目在执行完之后,除了有一份性能测试报告,啥过程性输出都没。这样的企业是怎么积累性能经验的?在性能项目中,多做一些归档整理,以备后面项目查阅,并实现技术积累。

9.2 结果输出

  • 性能场景执行结果记录的报告(性能测试报告)
  • 性能调优报告
9.2.1 性能项目测试报告
  1. 报告一定要有结论,而不是给出一堆“资源使用率多少”、“TPS多少”、“响应时间多少”这种描述类总结语。性能结果都在这个报告中了,谁还看不见?还要你复述?要给出“当前系统可支持XXX并发用户数,XXX在线用户数”这样的结论
  2. 不要用“可能”、“或许”、“理应”这种模棱两可词,否则就是在耍流氓
  3. 要有对运维工作的建议,也要给出关键性能参数的配置建议,如线程池、队列、超时等
  4. 性能结果报告中要有对后续性能工作的建议
9.2.2 性能调优报告

调优报告才是整个性能项目的精华,调优报告中一定要记录下每一个性能问题的问题现象、分析过程、解决方案和解决效果。调优报告完全是一个团队技术能力的体现。

10 项目风险分析

常见风险:

  1. 业务层的性能需求不明确
  2. 环境问题
  3. 数据问题
  4. 业务模型不准确
  5. 团队间协调沟通困难
  6. 瓶颈分析不到位,影响进度

在我们这项目中,比较大的风险就是:

  1. 硬件资源有限。
  2. 项目时间不可控,因为出问题,没人支持,只能自己搞

11 总结

性能方案是一个性能项目的重要输出。若你在项目中做快速迭代,可能并不需要写如此复杂并且重量级的文档。因为文档里描述的很多工作都已经做过了,你可能只需要跟着版本去做迭代比对。

但对一个完整项目,性能方案很重要。因为它指导这项目的整个过程。性能方案中:业务模型、性能指标、系统架构图、场景设计、监控设计等都对整个项目的质量起到关键作用。

12 FAQ

微服务电商项目介绍:https://mp.weixin.qq.com/s/a8nDBbkuvSjreaCxuM2PuQ

看到物理机器2它的available才几百M,这会不会影响压测,要不要调大一点再压测?这个值是看还有多少可用的,但是要不要调大,取决于有没有hard faults产生。

猜你喜欢

转载自blog.csdn.net/qq_33589510/article/details/132877809
03-