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

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

6 性能实施前提条件

6.1 硬件环境

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

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

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


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


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


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

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

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

6.2 工具准备

6.2.1 测试工具

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


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


6.2.2 监控工具

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


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


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


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


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

6.3 数据准备

6.3.1 基础数据

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

  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控制业务比例:

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

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

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


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

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

那么在TPS曲线中,

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

③ 稳定性场景

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

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

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

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

  • 有的系统是有固定的运维周期,比如说会设定固定的Job来做归档之类的动作
  • 有的系统是根据巡检的结果做相应的动作
  • 稳定性要做的就是保证在运维周期之内业务能正常。 所以,在性能的稳定性场景中,要完全覆盖业务容量。

如下图:

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

稳定性时长=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 全局监控

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

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

7.2.2 定向监控

在有问题时才使用:

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

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产生。

相关实践学习
通过性能测试PTS对云服务器ECS进行规格选择与性能压测
本文为您介绍如何利用性能测试PTS对云服务器ECS进行规格选择与性能压测。
目录
相关文章
|
2月前
|
缓存 NoSQL 应用服务中间件
性能基础之大型网站架构演化(整理篇)
【2月更文挑战第14天】性能基础之大型网站架构演化(整理篇)
45 1
性能基础之大型网站架构演化(整理篇)
|
6月前
|
分布式计算 NoSQL Java
局部性原理——各类优化的基石(2)
CDN的全称是Content Delivery Network,即内容分发网络(图片来自百度百科) 。CDN常用于大的素材下发,比如图片和视频,你在淘宝上打开一个图片,这个图片其实会就近从CDN机房拉去数据,而不是到阿里的机房拉数据,可以减少阿里机房的出口带宽占用,也可以减少用户加载素材的等待时间。
40 0
|
2月前
|
存储 并行计算 算法
【深度挖掘Java性能调优】「底层技术原理体系」深入挖掘和分析如何提升服务的性能以及执行效率(性能三大定律)
【深度挖掘Java性能调优】「底层技术原理体系」深入挖掘和分析如何提升服务的性能以及执行效率(性能三大定律)
38 0
|
2月前
|
缓存 编译器 数据处理
【C/C++ 性能优化】循环展开在C++中的艺术:提升性能的策略与实践
【C/C++ 性能优化】循环展开在C++中的艺术:提升性能的策略与实践
56 0
|
2月前
|
存储 缓存 监控
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(场景问题分析+性能影响因素)
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(场景问题分析+性能影响因素)
36 0
|
6月前
|
存储 消息中间件 数据库
Milvus性能优化提速之道:揭秘优化技巧,避开十大误区,确保数据一致性无忧,轻松实现高性能
Milvus性能优化提速之道:揭秘优化技巧,避开十大误区,确保数据一致性无忧,轻松实现高性能
Milvus性能优化提速之道:揭秘优化技巧,避开十大误区,确保数据一致性无忧,轻松实现高性能
|
6月前
|
存储 缓存 NoSQL
局部性原理——各类优化的基石(1)
学过计算机底层原理、了解过很多架构设计或者是做过优化的同学,应该很熟悉局部性原理。即便是非计算机行业的人,在做各种调优、提效时也不得不考虑到局部性,只不过他们不常用局部性一词。如果抽象程度再高一些,甚至可以说地球、生命、万事万物都是局部性的产物,因为这些都是宇宙中熵分布布局、局部的熵低导致的,如果宇宙中处处熵一致,有的只有一篇混沌。
41 0
|
7月前
|
运维 监控 架构师
03-揭秘大厂性能方案的奥秘!(上)
03-揭秘大厂性能方案的奥秘!
50 0
|
9月前
|
监控 安全 Java
高性能服务器设计思路和方案
高性能服务器设计思路和方案
73 0