极客时间已完结课程限时免费阅读

06丨倾囊相授:我毕生所学的性能分析思路都在这里了

06丨倾囊相授:我毕生所学的性能分析思路都在这里了-极客时间

06丨倾囊相授:我毕生所学的性能分析思路都在这里了

讲述:高楼

时长43:26大小24.86M

我还年轻的时候,经常听一些大会或者演讲。有些人说,思路逻辑非常重要。我那时就想,你肯定是瞎忽悠的,因为我怎么就没听懂你说的思路呢?
而现在轮到自己来写或者讲一些东西的时候,才发现他们说得很对,而我之所以不理解,也是有原因的。
性能分析思路和具体的实现之间,有一道鸿沟,那就是操作的能力。之前我为什么听不懂那些人的思路,其实是因为我没有操作的功底。
而有了操作的功底之后,还有一个大的鸿沟要越过去,那就是从操作到对监控计数器的理解。这一步可以说让很多性能测试人员都望而却步了。
但是这还不算完,这一步迈过去之后,还有一个跳跃,就是相关性分析和证据链分析的过程。
如此一来,就会得到一张性能测试分析的能力阶梯视图,如下:
工具操作:包括压力工具、监控工具、剖析工具、调试工具。
数值理解:包括上面工具中所有输出的数据。
趋势分析、相关性分析、证据链分析:就是理解了工具产生的数值之后,还要把它们的逻辑关系想明白。这才是性能测试分析中最重要的一环。
最后才是调优:有了第 3 步之后,调优的方案策略就有很多种了,具体选择取决于调优成本和产生的效果。
那么怎么把这些内容都融会贯通呢?下面我们就来说说性能测试分析的几个重要环节。
应该说,从我十几年的性能工作中,上面讲的这些内容是我觉得最有价值的内容了。在今天的文章中,我们将对它做一次系统的说明。我先把性能分析思路大纲列在这里:
瓶颈的精准判断;
线程递增的策略;
性能衰减的过程;
响应时间的拆分;
构建分析决策树;
场景的比对。

瓶颈的精准判断

TPS 曲线

对性能瓶颈做出判断是性能分析的第一步,有了问题才能分析调优。
之前有很多人在描述性能测试的过程中,说要找到性能测试中曲线上的“拐点”。我也有明确说过,大部分系统其实是没有明确的拐点的。
举例来说,TPS 的视图如下:
TPS图1
显然,这是一个阶梯式增加的场景,非常好。但是拐点在哪呢?有人说,显然在 1200TPS 左右的时候。也有人说了,显然是到 1500TPS 才是拐点呀。但是也有人说,这都已经能到 2000TPS 了,显然 2000TPS 是拐点。
我们再来看一下这张图对应的响应时间视图:
响应时间图1
是不是有人要说响应时间为 4.5ms 时是拐点了?
其实这些对拐点的判断,都是不合理的。如果我们对 TPS 的增加控制得更为精准的话,那么这个 TPS 的增加是有一个有清晰的弧度,而不是有一个非常清晰的拐点。
但是至少我们可以有一个非常明确的判断,那就是瓶颈在第二个压力阶梯上已经出现了。因为响应时间增加了,TPS 增加得却没有那么多,到第三个阶梯时,显然增加的 TPS 更少了,响应时间也在不断地增加,所以,性能瓶颈在加剧,越往后就越明显。
那么我们的判断就是:
有瓶颈!
瓶颈和压力有关。
压力呈阶梯,并且增长幅度在衰减。
如果你觉得上面的瓶颈还算清晰的话,那么我们再来看一张图:
TPS图2
在这个 TPS 的曲线中,你还能判断出拐点在哪吗?
显然是判断不出来拐点的,但是我们根据图得出以下几个结论:
有瓶颈!
瓶颈和压力有关。
压力也是阶梯的,但是并没有明确的拐点。
我们再来看一个 TPS 图:
TPS图3
看到这张图,是不是明显感觉系统有瓶颈呢?那么瓶颈是不是和压力大小有关呢?
这种比较有规律的问题,显然不是压力大小的原因。为什么呢?因为 TPS 周期性地出现降低,并且最大的 TPS 也都恢复到了差不多的水位上。所以,即使是压力降低,也最多降低最大的 TPS 水位,会让问题出现得更晚一点,但是不会不出现。
综合以上,如果画一个示意图的话,TPS 的衰减过程大概会如下所示:
随着用户数的增加,响应时间也在缓慢增加。
TPS 前期一直都有增加,但是增加的幅度在变缓,直到变平。
在这样的趋势图中,我们是看不到明确的拐点的。但是我们能做的清晰的判断就是:有瓶颈!
所以对 TPS 曲线来说,它可以明确告诉我们的就是:
有没有瓶颈:其实准确说所有的系统都有性能瓶颈,只看我们在哪个量级在做性能测试了。
瓶颈和压力有没有关系:TPS 随着压力的变化而变化,那就是有关系。不管压力增不增加,TPS 都会出现曲线趋势问题,那就是无关。
这时你可能会问,为什么不看响应时间就武断地下此结论呢?其实响应时间是用来判断业务有多快的,而 TPS 才是用来判断容量有多大的。

响应时间的曲线

我们还是来看看响应时间,下面看一张响应时间图:
它对应的线程图是:
多明显的问题,随着线程的增多,响应时间也在增加,是吧。再来看它们对应的 TPS 图:
到第 40 个线程时,TPS 基本上达到上限,为 2500 左右。响应时间随着线程数的增加而增加了,系统的瓶颈显而易见地出现了。
但是,如果只让你看 TPS 曲线,你是不是也会有同样的判断?那就是:有瓶颈!并且和压力有关?所以说,其实 TPS 就可以告诉我们系统有没有瓶颈了,而响应时间是用来判断业务有多快的。
后面我们还会提到响应时间会是性能分析调优的重要分析对象。

线程递增的策略

讲完响应时间之后,我们再来看下线程递增。
在见识了很多性能测试人员做的场景之后,必须得承认,有些场景的问题太多了。
首先,我们来看两个场景的执行对比。
场景 1 的线程图:
场景 1 的 TPS 图:
场景 1 的响应时间图:
场景 2 的线程图:
场景 2 的 TPS 图:
场景 2 的响应时间图:
这两个场景的比对如下:
有了这些对比数据之后,你是不是觉得哪里似乎是有问题的?
对的!
TPS 都是达到 400,但两个场景中线程递增的策略不同,产生的响应时间完全不同。虽然都没有报错,但是第一种场景是完全不符合真实的业务场景的。这是为什么呢?
在场景的执行过程中,首先,响应时间应该是从低到高的,而在场景 1 中不是这样。其次,线程应该是递增的,而场景 1 并没有这样做(这里或许有人会想到秒杀的场景,认为场景 1 符合秒杀的业务设定,这个问题我们稍后提及)。最后,在两个场景中,TPS 的上限都达到了 400TPS。但是你可以看到,在场景 2 中,只要 40 个线程即可达到,但场景 1 中居然用到了 500 线程,显然压力过大,所以响应时间才那么长。
其实在生产环境中,像场景 1 这样的情形是不会出现的。如果它出现了,那就是你作为性能测试的责任,因为你没有给出生产环境中应该如何控制流量的参数配置说明。
同时,我们从上面的场景对比可以看到,对一个系统来说,如果仅在改变压力策略(其他的条件比如环境、数据、软硬件配置等都不变)的情况下,系统的最大 TPS 上限是固定的
场景 2 使用了递增的策略,在每个阶梯递增的过程中,出现了抖动,这就明显是系统设置的不合理导致的。设置不合理,有两种可能性:1. 资源的动态分配不合理,像后端线程池、内存、缓存等等;2. 数据没有预热。
我们再回到之前说的秒杀场景。
说到秒杀场景,有人觉得用大线程并发是合理的,其实这属于认识上的错误。因为即使线程数增加得再多,对已经达到 TPS 上限的系统来说,除了会增加响应时间之外,并无其他作用。所以我们描述系统的容量是用系统当前能处理的业务量(你用 TPS 也好,RPS 也好,HPS 也好,它们都是用来描述服务端的处理能力的),而不是压力工具中的线程数。这一点,我在第 5 篇文章中已经做了详细的解析,你可以回去再看看。
那么,对于场景中线程(有些工具中叫虚拟用户)递增的策略,我们要做到以下几点:
场景中的线程递增一定是连续的,并且在递增的过程中也是有梯度的。
场景中的线程递增一定要和 TPS 的递增有比例关系,而不是突然达到最上限。后面在场景的篇幅中我们会再说它们之间的比例关系。
上面两点针对的是常规的性能场景。对于秒杀类的场景,我们前期一定是做好了系统预热的工作的,在预热之后,线程突增产生的压力,也是在可处理范围的。这时,我们可以设计线程突增的场景来看系统瞬间的处理能力。如果不能模拟出秒杀的陡增,就是不合理的场景。
这里给出我做性能场景递增的经验值:
当然这里也不会是放在哪个系统中都适合的递增幅度,你还是要根据实际的测试过程来做相应的判断。
有了这些判断之后,相信大家都能做出合理的场景来了。

性能衰减的过程

有了瓶颈的判断能力,也有了线程递增的意识,那么下面在场景执行中,我们就要有判断性能衰减的能力了吧。
来,我们先看一个压力过程中产生的结果图。
在递增的压力过程中,随着用户数的增加。我们可以做几次计算。
第一次计算,在线程达到 24 时,TPS 为 1810.6,也就是每线程每秒发出 75.44 个请求。
第二次计算,在线程达到 72 时,TPS 为 4375.1,也就是每线程每秒发出 60.77 个请求。
第三次计算,在线程达到 137 时,TPS 为 5034,也就是每线程每秒发出 36.74 个请求。
通过这三次计算,我们是不是可以看到,每线程每秒发出的请求数在变少,但是整体 TPS 是在增加的。
我们有很多做性能测试的人,基本上,只看 TPS 和响应时间的时候,在上面这个示例中,肯定会一直往上加用户。虽然响应时间在增加,但是增加得也不多嘛。
但实际上,通过我们的计算可以知道,性能是在不断地衰减的。我们来看一张统计图:
通过红线的大致比对可以知道,当每线程每秒的请求数降到 55 左右的时候,TPS 就达到上限了,大概在 5000 左右,再接着往上增加线程已经没有用了,响应时间开始往上增加了。
这就是性能衰减的过程(题外话,在上图中,其实还有一个问题,就是在红线前面,性能在上升的过程中有几次抖动,这个抖动到后面变大了,也变频繁了,如果这是必然出现的抖动,那也是配置问题,希望你注意到这一点)。
为什么要这么细致地描述性能衰减的过程呢?
其实我就是想告诉你,只要每线程每秒的 TPS 开始变少,就意味着性能瓶颈已经出现了。但是瓶颈出现之后,并不是说服务器的处理能力(这里我们用 TPS 来描述)会下降,应该说 TPS 仍然会上升,在性能不断衰减的过程中,TPS 就会达到上限
这也是前面我说的,性能瓶颈其实在最大 TPS 之前早就已经出现了。
那么我们是不是应该在性能衰减到最大 TPS 时就停止场景呢?这个不一定的哦。
因为停不停场景,取决于我们的场景目标,如果我们只是为了得到最大 TPS,那确实可以停止场景了。但是,如果我们要扩大化性能瓶颈,也就是说为了让瓶颈更为明显,就完全不需要停止场景,只要不报错,就接着往上压,一直压到我们要说的下一个话题——响应时间变长,需要拆分。

响应时间的拆分

在性能分析中,响应时间的拆分通常是一个分析起点。因为在性能场景中,不管是什么原因,只要系统达到了瓶颈,再接着增加压力,肯定会导致响应时间的上升,直到超时为止。
在判断了瓶颈之后,我们需要找到问题出现在什么地方。在压力工具上看到的响应时间,都是经过了后端的每一个系统的。
那么,当响应时间变长,我们就要知道,它在哪个阶段时间变长了。
我们看下这张图。
这应该是最简单的一个压力测试逻辑了。一个应用,一个 DB,结果也拆分出了 8 个时间段,这还是在我没有加上压力工具自己所消耗的时间的情况下。
如果我们要分析压力工具中的响应时间,拆分的逻辑就是上面这个示意图。
但是在真实的场景中,基本上不是这样的。如果是内网,那基本上都是连在一个交换机上,所以通常是这样的:
在这样的拓扑中,我们仍然可以拆出来 t1 到 t8 的时间。只是实际动手的时候,思路一定要清晰,时间拆分是从哪里到哪里,要画出来,不能混乱。
我们有很多手段可以进行时间的拆分,当然要看我们的应用支持哪一种。
如果我们是这样的架构,拆分时间应该是比较清楚的。
首先我们需要查看 Nginx 上的时间。日志里就可以通过配置 upstream_response_time 得到日志如下信息:
14.131.17.129 - - [09/Dec/2019:08:08:09 +0000] "GET / HTTP/1.1" 200 25317 0.028 0.028
最后两列中,前面是请求时间的 28ms,后面是后端响应时间的 28ms。
同时,我们再到 Tomcat 上去看时间。
172.18.0.1 - - [09/Dec/2019:08:08:09 +0000] "GET / HTTP/1.1" 200 25317 28 27 http-nio-8080-exec-1
请求时间消耗了 28ms,响应时间消耗了 27ms。
接着再来看一下前端的时间消耗。
从这里可以看到,从发出请求到接收到第一个字节,即 TTFB 是 55.01ms,内容下载用了 11.75ms。从这就可以看得出 Nginx 基本上没消耗时间,因为它和 Tomcat 上的请求响应时间非常接近。
那么网络上的消耗时间怎么样呢?我看到有很多人用 TTFB 来描述网络的时间。先来说明一下,TTFB 中显然包括了后端一系列处理和网络传输的时间。如下图所示。
下面的紫色点是指要接收的内容。上面的红色线就是 TTFB。
如果接收完了呢?就是这个状态。
所以,我觉得用 TTFB 描述网络的健康状态并不合理。如果用 Content Download 来描述会更为合理。比如我们上面的这个例子中,那就是 11.75ms 下载了 25317 Bytes 的内容。
Tomcat 上基本上是消耗了处理的所有时间,当然这中间也包括了 MySQL 花费的时间。而前端看到的其他时间就消耗在了网络中。
在这个例子中,主要说明了响应时间怎么一步步拆。当然,如果你是下面这种情况的话,再一个个拆就比较辛苦了,需要换另一种方式。
你肯定想知道每个系统消耗了多长时间,那么我们就需要链路监控工具来拆分时间了。比如像这样来拆分:
从 User 开始,每个服务之间的调用时间,都需要看看时间消耗的监控。这就是时间拆分的一种方式。
其实不管我们用什么样的工具来监控,最终我们想得到的无非是每个环节消耗了多长时间。用日志也好,用链路监控工具也好,甚至抓包都可以。
当我们拆分到了某个环节之后,就有了下一步的动作:构建分析决策树。

构建分析决策树

关于分析决策树,我在很多场合也都有提及。
分析决策树,对性能测试分析人员实在是太重要了,是性能分析中不可或缺的一环。它是对架构的梳理,是对系统的梳理,是对问题的梳理,是对查找证据链过程的梳理,是对分析思路的梳理。它起的是纵观全局,高屋建瓴的指导作用
性能做到了艺术的层级之后,分析决策树就是提炼出来的,可以触类旁通的方法论。
而我要在这里跟你讲的,就是这样的方法论。
应该说,所有的技术行业在面对自己的问题时,都需要有分析决策树。再广而推之的话,所有的问题都要有分析决策树来协助。
通过上面的几个步骤,我们就会知道时间消耗在了哪个节点上。那么之后呢?又当如何?
总要找到根本的原因才可以吧,我画了如下的分析决策图:
从压力工具中,只需要知道 TPS、响应时间和错误率三条曲线,就可以明确判断瓶颈是否存在。再通过分段分层策略,结合监控平台、日志平台,或者其他的实时分析平台,知道架构中的哪个环节有问题,然后再根据更细化的架构图一一拆解下去。
我在这里,以数据库分析和操作系统分析举一下例子。
首先我们看一下数据库分析决策树。
比如针对 RDBMS 中的 MySQL,我们就可以画一个如下的决策树:
由于这里面的内容实在过多,无法一次性展现在这里。我举几个具体的例子给你说明一下。
MySQL 中的索引统计信息有配置值,有状态值。我们要根据具体的结果来判断是否需要增加 key_buffer_size 值的大小。比如这种就无所谓了。
Buffer used 3.00k of 8.00M %Used: 0.0004
从上面的数据可以看到,key buffer size 就用到了 4%,显然不用增加。
再比如,我们看到这样的数据:
__Tables_______________________
Open 2000 of 2000 %Cache: 100.00
Opened 15.99M 4.1/s
这就明显有问题了。配置值为 2000 的 Open Table Cache,已经被占满了。显然这里需要分析。但是,看到状态值达到配置值并不意味着我们需要赶紧加大配置值,而是要分析是否合理,再做相应的处理。比如说上面这个,Table 确实打开得多,但是如果我们再对应看下这一条。
Slow 2 s 6.21M 1.6/s
你是不是觉得应该先去处理慢 SQL 的问题了?
关于数据库的我们就不举更多的例子了。在这里只是为了告诉你,在分析决策树的创建过程中,有非常多的相互依赖关系。
然后我们再来看一下操作系统分析决策树,我在这里需要强调一下,操作系统的分析决策树,不可以绕过。
如果你想到操作系统架构图就头大,那么这时候应该觉得有了希望。那就是我觉得操作系统上的问题判断是比较清晰的,所以基于此决策树,每个人都可以做到对操作系统中性能问题的证据链查找。
但是!对嘛,总得有个但是。
对操作系统的理解是个必然的前提。我看过很多人写的操作系统性能分析方面的书籍或资料,发现大部分人把描述计数器的数值当成性能分析。
怎么理解这句话呢?比如说
“CPU 使用率在 TPS 上升的过程中,从 10% 增加到 95%,超过了预期值。” “内存使用率达到 99%,所以是瓶颈点。” “I/O 使用率达到 100%。” 等等。
像这样的描述,在我的性能团队中,一定会被骂回去重写。我要这些描述有什么用?我要的是为什么达到了这样的值,原因在哪?怎么解决?
就像分析决策树中所描述的那样,性能工程师要做的是一步步地细化分析,给出最终的原因。
有人说,如果按这个路子,似乎操作系统的分析并不复杂嘛。大概三五个命令就可以跳到代码层了。是的,对于操作来说,确实不多,但是对于判断来说,那就复杂了。举个例子来说明一下:
看到这样的图,你是不是有种手足无措的感觉?中断能占 40%,sy CPU 也能占 40%。这系统还用干业务的事吗?全干自己的事去了,可见操作系统有问题!你是不是要做这个判断了?
而实际情况是,这个主机上只有一个网卡队列,而请求量又比较大。
所以要解决的是网卡队列的问题,至于怎么解决,那手段就多了。可以换个服务器,可以多加几个队列,可以多接几个节点......
以上只是给出几个性能分析过程中常见的决策树示例。在后续的分析过程实例中,我们将秉承着这种分析思路,一步步地走到瓶颈的面前。

场景的比对

为什么要写这一部分呢?因为我看到很多人对瓶颈的判断,并不那么精确,所以想写一下场景比对的建议。
其实简单来说,就一句话:当你觉得系统中哪个环节不行的时候, 又没能力分析它,你可以直接做该环节的增加。
举例来,我们现在有一个如下的架构:
可以得到这样的结果:
从 TPS 曲线中,我们可以明显看到系统是有瓶颈的,但是并不知道在哪里。鉴于系统架构如此简单,我们索性直接在某环节上加上一台服务器,变成这样:
然后得到如下数据:
哟,没好使!
怎么办?再接着加其他节点,我加了更多的 JMeter 机器。
再来看下结果:
真巧,TPS 增加了!
看到了吧,这就是我说的场景比对。
当我们不知道系统中哪个环节存在性能瓶颈时,对架构并不复杂的系统来说,可以使用这样的手段,来做替换法,以快速定位问题。

总结

在这一篇中,我说到了瓶颈的精准判断、线程递增的策略、性能衰减的过程、响应时间的拆分、构建分析决策树以及场景的比对,这几个环节,是性能分析过程中非常重要的环节。
从我的经验上来说,这一篇文章可能是我工作十几年的精华所在了。而这里的每一个环节,又有非常多的细分,特别是构建分析决策树这一块,它需要太多的架构知识、系统知识、数据库知识等等。鉴于本文只是想起到一个提纲挈领的作用,所以无法展开描述,希望在后续的篇幅中,我们尽量细致拆解。

思考题

今天的内容虽然有点多,但总的来说,思路比较清晰,理解起来也比较容易。如果你认真学习了今天的内容,不妨思考两个问题,为什么线程递增过程不能断?构建分析决策树的关键是什么?
欢迎你在评论区写下你的思考,我会和你一起交流,也欢迎把这篇文章分享给你的朋友或者同事,一起交流一下。
分享给需要的人,Ta购买本课程,你将得18
生成海报并分享

赞 34

提建议

上一篇
05丨指标关系:你知道并发用户数应该怎么算吗?
下一篇
07丨性能测试工具:如何录制脚本?
unpreview
 写留言

精选留言(129)

  • zuozewei
    2019-12-27
    第一个问题:为什么线程递增过程不能断? 这里涉及开篇提到的性能分析能力 ——「趋势分析」。 就像之前提到的一样,分析性能数据趋势需要对一个时间序列数据的分析,一般采用「线性回归分析」算法。 回归分析研究的是多个变量之间的关系。它是一种预测性的建模技术,它研究的是因变量(目标)和自变量(预测器)之间的关系。这种技术通常用于预测分析,时间序列模型以及发现变量之间的因果关系。 假设有 N 个样本点,这里我们可以简单理解线性回归算法就是求一条直线 Y=f(X),使得各点到这个曲线的距离的绝对值之和最小。 在这种技术中,因变量(TPS)是连续的,自变量(线程数)可以是连续的也可以是离散的,回归线的性质是线性的。 但在性能测试中,由于系统本身的最大 TPS 上限是固定的,即服务端的处理能力(容量)是固定的,如果自变量(线程数)压力过大,那么系统平均处理时间(响应时间)会被拉长。不过这个时候其实瓶颈早就出现了。 所以在场景压测中的自变量(线程数)递增一定需要是连续的,并且在递增的过程中要有梯度的,且场景中的线程递增一定要和因变量(TPS) 的递增有比例关系,且不是突然达到最上限,这样才能准确找出系统的瓶颈点。 第二个问题:构建分析决策树的关键是什么? 决策树基本上就是把我们以前的分析经验总结出来,在做决策树的时候,一般会经历两个阶段:构造和剪枝。 概念简单来说: - 构造的过程就是选择什么属性作为节点的过程构造的过程就是选择什么属性作为节点的过程; - 剪枝就是给决策树瘦身,这一步想实现的目标就是,不需要太多的判断,同样可以得到不错的结果。之所以这么做,是为了防止“过拟合”现象的发生。 从性能分析角度来理解: - 构造:需要根据经验是对架构的梳理,是对系统的梳理,是对问题的梳理,是对查找证据链过程的梳理,是对分析思路的梳理; - 剪枝:需要对对不同时间序列性能数据的相关性分析,其核心就是要理解各个性能指标的关系,同时进行证据链查找,根据数据的变化来推断得出各种结论,比如故障判别、根因分析等。
    展开
    共 6 条评论
    85
  • 小呀么小二郎
    2020-03-16
    今天的内容有点多,写了份总结,正好梳理一下思路 本节内容主要讲了性能分析思路。从6个方面来分析: 首先,要准确的判断瓶颈点。通过什么来判断呢?TPS曲线。TPS曲线能够告诉我们系统是否有瓶颈,以及瓶颈是否与压力有关。为什么不需要响应时间曲线来判断呢?因为响应时间主要是用来判断业务快慢的。 其次,我们要确定我们设置的性能场景是正确的,线程是逐渐递增的,而不应该一上来就上几百个线程。原因:1、直接上几百个线程不符合一般情况下的真实场景。2、即使是秒杀场景也有个“数据预热”的过程(我的理解,数据预热跟线程递增应该差不多,有一个由小到大逐渐增加的过程)3、对于TPS已经到达上限的系统来说,除了响应时间的增加,没有其他作用。 再次,我们要拥有能判断性能衰减的能力。如何判断?分段计算每线程每秒的TPS,如果这个数值开始变少,那么性能瓶颈就出现了。此时再随着线程的增加,性能逐渐衰减,TPS逐渐达到上限。 然后,我们知道性能开始衰减了,那么是什么原因导致的衰减?此时就需要对响应时间进行拆分,拆分的前提需要熟悉系统的架构,拆分的目的是要知道每个环节消耗的时间,拆分的方法可以通过日志,可以通过监控工具,也可以通过抓包(抓包应该需要和日志配合吧?以老师的例子来说,能抓到tomcat的请求和响应时间吗?我感觉不能……) 再然后,最重要的地方到了,我们要逐步构建自己的分析决策树。随着性能分析经验的累加,我们需要整理并总结每次遇到的性能问题以及相对应的解决方法,同时我们还要不断扩充自己的知识库:系统架构、操作系统、数据库、缓存、路由等等,并将这些知识与经验结合起来。重新梳理,由大到小,由宏观到细节,去画出自己的分析决策树。 最后一点感觉是对第一条的补充,而且应该也是对小白(比如我)的一个提点,当我们刚开始进行性能分析,没有思路的时候,那就可以通过这种替换法来帮助我们快速定位问题。当然,这种方法比较适合简单的系统,如果系统很复杂,这样替换不一定方便了。 这节课很重要,但是像我这种没有实际分析调优经验的小白来说,看懂跟理解好像还是缺少了实际操作在里头。这篇大概需要练习后再反复的回看。 今天的思考题答案基本写在上面的总结里了,如果有理解不正确的地方请老师指正。最后,感谢老师把宝贵的经验分享给我们,老师辛苦啦!
    展开

    作者回复: 写的太好了。你是最认真的一个!

    共 3 条评论
    56
  • 吴小喵
    2019-12-27
    看到构建分析决策树就吓死了,数据库的知识,操作系统的知识都不懂啊,o(╥﹏╥)o

    作者回复: 慢慢来。反正不是吓死就是累死。

    14
  • rainbowzhouj
    2019-12-27
    第一个问题:不能断的原因是保证在测试过程中资源分配的合理性,减少偏差,便于分析出当前环境中的性能瓶颈点。否则断开后系统动态资源会重新分配,造成分析偏差。 第二个问题:构建分析决策树的关键好比如何画一棵树。先确定主干(主要流程),然后添枝干(组成部分),最后画树叶(定位问题)。从上到下,从左到右,拆分...... 总的体会感觉给我这种测试野路子出身的工程师,又梳理了一遍如何定位问题的方法。让我对之前的工作实践中地操作有了进一步地理解。并且重新审视目前我所处的阶段:操作能力待加强。感谢老师,读完文章感到意犹未尽,希望在后续的课程能更加精彩。
    展开

    作者回复: 多谢肯定。 一看评论就是练家子出身的。多做总结,就会有更多的收获。

    14
  • Geek_65c0a2
    2019-12-27
    这节课我也期待了好久。高老师写的字数多点,总感觉不够看👀

    作者回复: 编辑小美女说我文章写太长了。😣😣

    共 3 条评论
    10
  • hou
    2020-03-04
    请问老师,递增经验中, 为什么响应时间少,递增幅度小呢?

    作者回复: 响应时间小的话,每个线程产生的TPS就高呀。 所以线程增加的幅度就要小一点。如果线程增加多了,因为单TPS高所以压力增加的就快,这样不得于产生明显的性能梯度用来分析。

    共 4 条评论
    9
  • 土耳其小土豆
    2019-12-30
    看高老师的文件,感觉都能看懂,但是高老师的问题,我却回答不了,特别是第一个问题。

    作者回复: 练。你还年轻。

    7
  • 相看两不厌
    2020-11-11
    看了3遍,总结+疑问,希望高老师能回复 1. 判断是否存在瓶颈 通过tps曲线可得出的常见结论:压力越大,tps增幅越小,直至为零,存在瓶颈:tps规律性波动,压力只是将现象放大,存在瓶颈 通过响应时间曲线可得出的常见结论:随着压力增大,响应时间也增大,存在瓶颈 疑问:工作中经常是做高老师所谓的性能验证工作,通常测试环境操作系统相关配置就是和现网保持一致,尽量去测出应用和中间件配置的问题。经常会有疑问就是,接口达不到指标,不知道是不是在当前操作系统配置下,接口本身就是这样的能力了,不好判断是否接口存在问题。 2. 线程递增的策略 场景中的线程递增一定要连续,这样更符合真实场景,可能也给了系统预热的时间 工作中我一直都是按给定的并发数直接去压,看能否达到tps指标。以后我还是用梯度方式,可以看出趋势变化。 疑问:老师说随着响应时间,可以设置不同的梯度。我的理解是都可以按1平稳增加吧 3. 性能衰减的过程 老师通过例子展示的每个线程请求数降低,性能瓶颈就已经出现,其实还是响应时间增大了导致;但是瓶颈出现,并不意味着服务器的处理能力降低,相反,在并发数和响应时间达到某个点之前,处理能力就一直是增加的,事实就是在性能不断衰减的过程中,TPS达到上限。 4. 响应时间的拆分 可以通过日志打印请求响应时间、前端通过TTFB、复杂调用可以依靠调用链将点到点的时间拆分出来 工作中是绕过nginx,直接请求微服务接口进行压测,使用的工具就是调用链,真的非常方便 5. 构建分析决策树 这块感觉是重中之重,同时也是难上加难,我的理解是构建分析决策树是将可能影响性能的模块列出来后,再细分其下的属性、配置等,针对测试数据来判断是否为问题点。体现了性能工程师全面又专业的水准。 自己现在还差的很多,但是老师拿mysql举例还是给我实际工作有很大帮助。我工作中在msyql中就是加索引这一点,从来没像老师这样具体分析。后面详细学习下应用到工作中 6. 场景的比对 疑问:当5个jmeter,1台服务器时已经出现瓶颈,此时压力肯定够大了。但是添加2台服务器后,同样添加到10个jmeter,压力和服务器都在增加,TPS增加也是正常的啊。还是没能找出开始时的瓶颈所在。这节确实不理解。 总的来说,这篇文章在思路上确实让我学习到很多。希望后面能跟老师学习到具体的细节操作,才能在实战中游刃有余。
    展开

    作者回复: 看来这位同学是认真了。我也得认真回答下。 1,在固定的硬件配置下,要想知道接口有没有问题,就需要判断下接口响应时间的消耗,像apm、jvirsualvm,、arthas等工具都可以帮助你。这个判断是综合的判断,还要看硬件资源下是否已达到计算能力的最大值。再细节的就是要看方法级时间消耗是否合理。 2,按1平稳增加是可以的,只是在有些场景中,按1增加会需要比较长的时间,所以有时为了节省时间,我会增加的快一点。如果你有足够的时候,可以一直按1增加。这个没问题。 3. 理解正确! 4. 看来是真的实践了,这也是专栏的价值所在呀,能落地。哈哈。 5. 有思路就不怕落不了地。加油。不管是什么数据库,这思路都会有用。 6. 我写的应该在加了一台服务器之后,tps没有增加,所以才考虑增加多个jmeter的。这时压力有增加,就说明之前的压力不够。 我也觉得这篇是最有价值的,他的作用足以起到提纲挈领的作用。有疑问还可以接着问哈。

    6
  • 那片海
    2020-03-06
    高老师有3个问题问下: 1、 你给了一个 性能场景递增的经验值,是 基于响应值 每秒增加的 线程数,最终达到目标线程数? 2、 线程不能断,如果是测试稳定性场景 也需要这样梯度加压吗 可以直接1s内加压到最大线程数? 3、 在jmeter工具中,梯度加压 是使用默认的线程组 ramp up设置呢, 还是安装插件后使用Stepping Thread Group 和 concurrency Thread Group 设置 ?
    展开

    作者回复: 1. 是的。不过这个过程要多次调整。 2. 稳定性测试场景关注点不在递增那一阶段上,所以递增不递增都可以,就算递增用几分钟,也不影响稳定性测试整体场景的持续时间。 3. 这个都可以,取决于项目中要求的细致不细致了。装了插件我觉得会好一些,控制的细致。

    共 2 条评论
    5
  • qiaotaoli
    2020-01-06
    老师,再问一下,你文中发的递增经验值,后面的1-3指的是,比如第一个阶梯并发数是10,第二个阶梯并发数变为20-40,对么?另外,为什么响应时间越大后,并发幅度也变大呢?是因为响应时间变大后,并发幅度变化不大,可能看不出太大变化么?

    作者回复: 响应时间越短,并发递增越小。

    4
  • 学员141
    2021-12-03
    老师,一般哪些配置会影响抖动呢? 文章中“上升的过程中有几次抖动,这个抖动到后面变大了,也变频繁了,如果这是必然出现的抖动,那也是配置问题”

    作者回复: 最大最小空闲线程数之类的就会影响 。

    3
  • Geek_fbce88
    2020-09-14
    线程数是100,平均响应时间是0.2秒,没有设置几个点等,请问并发是500吗?因为一秒钟发送了500个请求

    作者回复: 对的。

    3
  • suke
    2020-03-09
    关于线程递增的策略,基本几千的并发数就需要多台jmeter去分布式的压了,当压测事件持续几个小时的时候最后生成的压测报告都很大都有几个g,有很大概率生成报告失败,对于这个问题老师有什么好的实践经验么

    作者回复: Jmeter+influxdb+grafana实时输出。

    共 2 条评论
    3
  • hou
    2020-02-29
    请求时间消耗了 28ms,响应时间消耗了 27ms。nginx接到请求的刹那,记录下请求时间,这是一个时间点,消耗28ms一般是在做什么呢,不应该只是一个时间点吗

    作者回复: 不是。请求时间是包括了进来和出去的时间,响应是记录的后端的时间。所以请求时间其实是一个时间段,不是时间点。

    3
  • 筱の简單
    2020-02-19
    1、为什么线程递增过程不能断? 因为场景中的线程递增且连续符合业务实际场景,可以较好的判断系统瓶颈。 2、构建分析决策树的关键是什么? 构建分析决策树的关键是对架构的梳理,对系统的梳理,对问题的梳理,对查找证据链过程的梳理,对分析思路的梳理。它起的是纵观全局,高屋建瓴的指导作用。
    展开

    作者回复: 理解的很对!

    3
  • SHATAN CLASS
    2021-03-12
    老师好,这篇我看了3遍了,非常喜欢您的课程,觉得您给到的观念和层次感都比较足。 但是其实在很多实际项目中寻在几个问题: 1、性能需求都不明确; 2、测试人员对系统的架构不熟悉,那就更不用谈什么性能分析和调优了。 针对这两点,老师有什么更好的解决方案吗?

    作者回复: 1. 只有找相关的人去沟通。或者拿生产数据统计分析。 2. 这个只能学习了,没啥捷径。

    共 2 条评论
    2
  • 你比昨天快乐🌻
    2020-03-17
    再次来看收获又不一样了。对于秒杀类的场景,我们前期一定是做好了系统预热的工作的,请问这句话中怎么理解系统预热,如何预热?

    作者回复: 举例来说,redis中在执行前先加载数据进去。像id之类的提前生成。

    2
  • hou
    2020-03-04
    老师,前面我们约定了性能指标用TPS来描述。但是在性能衰减的例子中,图1是请求数,您在描述中把请求数描述成TPS,这个让我很难理解。这里为什么请求数就成了TPS呢?

    作者回复: 在整个专栏中,我都是用TPS这个概念来描述压力的。没有用请求数来描述。 请求数和事务的关系就是,当只有一个请求时,那就不用定义事务了,直接可以把请求数每秒当成TPS。

    2
  • 伊森
    2020-02-09
    高老师,请问本节展示的四幅图:请求每秒、响应时间、线程数和请求/线程,都是jmeter自带的那个HTML报告生成的吗?如果是我没有找到请求每秒和请求/线程这两幅图,另外响应时间和线程数两幅图分别是对应的 Response Times Over Time和Active Threads Over Time吗?请帮忙确认一下在哪里找到这4幅图吗?谢谢

    作者回复: 是我拿原始数据用excel生成的。

    共 2 条评论
    2
  • 夜空中最亮的星
    2020-01-15
    果然是倾囊相授,谢谢老师xxe

    作者回复: 多谢支持。

    2