This commit is contained in:
louzefeng
2024-07-11 05:50:32 +00:00
parent bf99793fd0
commit d3828a7aee
6071 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,153 @@
<audio id="audio" title="09 | 性能测试的种类:如何快准狠地抓住一个测试的本质?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/12/6e/127dadddc70d5cba60e68e074258e16e.mp3"></audio>
你好,我是庄振运。
从这一讲开始我们讨论性能测试。性能测试是一种特殊的软件测试,它的目的是**确保软件应用程序在一定的负载流量下运行良好**。性能测试是性能分析和性能优化的基础,它的目标是**发现和性能相关的各种问题和性能瓶颈,从而进一步去消除错误和性能瓶颈**。
由于性能测试本身就有好多种类;加上各种测试之间的界限其实很模糊,这就造成了很多人理解上的混乱。
比如大家在工作讨论时,经常说做性能测试,但对于做什么样的“性能测试”,每个人有不同的看法,而且又经常表达不清。这就造成来交流不畅,甚至是误解,从而严重地影响了工作的速度。我见过很多次因为对性能测试定义和交代不清,造成了老板和员工之间/员工和员工之间的理解误差。
性能测试的种类颇多,各自有不同的测试目的、测试环境、负载等等;这里面最重要的是测试目的和负载的大小变化。我们这一讲就一起来分一下类。
## 性能测试的分类方式
性能测试如何分类呢?我们需要从几个方面来看,包括测试目的、测试环境、负载流量、测试对象、负载数据、黑盒白盒等。
### 测试目的
测试目的是最重要的方面。大体上有几种目的:
1. 测量服务速度Speed确定程序是否能够快速地响应用户的请求这个服务速度一般包括延迟和吞吐率两个指标。速度通常是应用程序最重要的属性之一因为运行缓慢的应用程序容易丢失用户。
1. 测量可扩展性Scalability确定应用程序是否可以在用户负载和客户流量增大情况下还能正常地运行。
1. 测量稳定性Stability确定在各种极端和恶劣环境下应用程序是否能稳定运行。
1. 测量性能瓶颈Performance Bottleneck性能瓶颈是应用程序和系统中的最影响整体性能的因素。瓶颈是指某个资源不足而导致某些负载下的性能降低。一些常见的性能瓶颈是CPU、内存、网络、存储等。
### 测试环境
性能测试的环境也有几种,主要是开发环境还是生产环境。开发环境里面更多的是简单的测试来发现一些明显问题,而生产环境测试一般是开发环境测试通过后才进行的。
### 负载流量
根据测试的负载大小来分:是小流量,正常流量,还是超大流量。除了大小,负载变化的速度也需要考虑。
### 测试对象
测试的对象可以是只针对一个代码功能,或是整个代码模块,亦或是整个系统。
### 负载数据
测试的负载数据可以是真正的生产环境中的请求和数据,比如终端客户的网站请求和上传数据,也可以是人工模拟出来的请求及数据。
### 黑盒白盒
如果把被测试的对象当作一个整体,不关心它的内部工作机理,也就是把它当作一个黑盒子,那么这种测试就是黑盒测试。反之,如果你也关心它的内部构件和内部设计,就是把它当作白盒子来测试。
## 性能测试的种类
我们现在看看你可能经常会提到的各种测试包括负载测试、容量测试、压力测试、断点测试、瓶颈测试、尖峰测试、耐力测试、基准测试、可扩展性测试和冒烟测试这10种。我分别说说它们是什么特点尽量用刚刚讲过的分类方式归归类并且适当举例说明。
需要说明的是,业界对于不同的测试类别其实也是各说各道,没有特别统一而严格的定义。我也是尽我所能,根据我的经验和实践来帮你理一理。
因为性能测试的种类多,我尽量把它们按照某种方式归类一下,帮助你理解和记忆。大体上可以按照负载流量的大小分成三类:低流量、中等流量和高流量。这里的流量高低是相对于生产环境中的流量而言的。当然,它们的实际界限其实很模糊。
<img src="https://static001.geekbang.org/resource/image/de/0c/dea330b04f4c81c71ab727b579e23b0c.png" alt="">
### 冒烟测试Smoke Testing
冒烟测试是开发人员在开发环境里执行的简单测试,以确定新的程序代码不出故障。冒烟测试目的是确认系统和程序基本功能正常。冒烟测试的执行者往往就是开发人员,但有时也让运维人员参与。
### 耐力测试Endurance Testing和浸泡测试Soak Testing
耐力测试或者耐久测试有时也叫浸泡测试是一种非功能性测试。耐力测试是长时间测试具有预期负载量的系统以验证系统的行为是否正常。举一个例子假设系统设计工作时间是3小时我们可以对这一系统进行超过3小时的测试比如持续6小时的耐力测试以检查系统的耐久性。
执行耐力测试最常见的用例是暴露某些不易重现的问题,如内存问题、系统故障或其他随机问题。
这里的偏重点是**测试时间**,因为有些程序和系统的问题只有在长期运行后才暴露出来。一个最明显的例子就是内存泄漏。一个程序或许短时间内运行正常,但是如果有内存泄漏,只要运行时间足够,就一定会暴露出这个问题。
### 基准测试Benchmark Testing/性能回归测试Performance Regression Testing
基准测试或者性能回归测试是着重“前后”对比的测试。
这种测试往往是开发过程的一部分,一般不需要具体的性能要求。代码的演化过程中经常需要确保新的代码不会对整个模块或系统的性能产生任何不好的影响。最简单的方法是对代码修改前后进行基准测试,并比较前后的性能结果。执行基准测试的重点是**保证前后测试环境的一致**,比如负载流量的特征和大小。
### 负载测试Load Testing
负载测试用于验证被测试系统或者程序是否可以处理预期的负载流量,并验证正常和峰值负载条件下的系统和程序行为。这里的负载可以是真正的客户请求,也可以是仿真的人工产生的负载。
我认为负载测试的定义有时太广泛和模糊,很多其他测试都可以看作是负载测试的一种,比如马上就要讲到的容量测试,其实就是一种负载测试。
### 断点测试Breakpoint Testing
断点测试类似于压力测试或者容量测试。这种测试的过程是随着时间的推移而增大流量负载,同时监视系统的预定故障条件。
断点测试也可以用来确定系统将达到其所需规范或服务水平协议的最大容量,并且自动采取措施来纠正或者缓解。比如云计算环境中,我们可以设置某种性能断点,用它们来驱动某种扩展和伸缩策略。
比如一种性能断点可以是根据用户的访问延迟。如果延迟性能测量的结果是已经超过预定的阈值,就自动进行系统容量调整,比如增加云计算的服务器。反之,系统容量也可以根据断点的规则来减少,以节省成本。如下图所示。
<img src="https://static001.geekbang.org/resource/image/01/d6/019067e2d02744e7ad7d4ff754523fd6.png" alt="">
### 尖峰测试Spike Testing
尖峰测试用于确定系统在负载(比如用户请求数)突然变化时的系统行为。这种测试是通过突然增加或减少由用户产生的负载来观察系统的行为。
测试的目标是确定性能在这样的场景下是否会受损,系统是否会失败,或者是否能够处理负载的显著变化。尖峰测试的核心是**负载变化的突然性**,所以也算是一种压力测试。
### 可扩展性测试Scalability Testing
可扩展性(或者叫可伸缩性)测试用于确定一个程序和系统的非功能性特征能不能在变化的环境里合理扩展。这里的环境变化包括系统环境的变化、负载量的大小、请求的多样性、数据量的大小等。
在系统环境变化时,同步的测量和观察各种性能指标,并进行数据的分析,从而确定在各种环境下被测试系统的可扩展性。如下图所示。
这个测试的主要目的是了解系统在什么样的环境中,以及什么样的变化会导致系统不能扩展。发现这些环境后,可以进一步有针对性的分析和加强。
<img src="https://static001.geekbang.org/resource/image/ae/12/aed41953ab37b10ffabab3b12c283012.png" alt="">
### 容量测试Capacity Testing
容量测试或者叫体积测试Volume Testing是用于确定一个单位容量能够支持的最大负载。比如一个程序运行在某种服务器上我们有时需要知道每台服务器能够支持的最大负载例如客户数从而决定需要部署多少台服务器才能满足预定的总负载要求。
容量测试一般是会不断增大负载,并且不断地测量各种性能指标。在性能目标变得不可接受之前,系统和程序可以成功处理的负载大小,就是单位容量可以承担的负载。为了尽量让得到的结果匹配实际生产环境,采用的负载流量最好是真正的生产环境的请求和数据。
正常生产环境中的流量和数据或许不够大到让一台服务器超载,因此我们需要解决这个问题。很多公司的解决方案是把其他服务器上的请求重定向到某一台被测试服务器,从而让这台服务器适度超载。这种机制我后面会用一讲专门讨论。
容量测试是确保系统稳定的重要一环。只有进行彻底的容量测试,并有相对应问题的解决方案,才可以使我们能够避免将来出现潜在的超载问题,例如增加的用户数或增加的数据量。
如下图所示,容量测试至少包含三个部分:可调节的流量负载、性能的测量、可以接受的性能指标。这三个部分一起就可以决定单位容量(比如一台服务器)的最大负载容量。这个数据可以帮助我们做各种决策,包括预估系统能负担的总负载;或者根据预期负载来决定部署多少台服务器。
<img src="https://static001.geekbang.org/resource/image/0d/36/0da67807c884dace487cb8f950bed136.png" alt="">
### 瓶颈测试Bottleneck Testing
瓶颈测试其实可以看作一种特殊的压力测试。它的目的是找到被测试系统和程序的最制约的资源类型比如CPU或者存储。瓶颈测试并不局限于只找到最制约的一个瓶颈它也可以同时找多个性能瓶颈。
找多个性能瓶颈的的意义主要有两点:
1. 如果最制约的瓶颈资源解决了,那么其他制约资源类型就自动会成为下一个瓶颈,所以需要未雨绸缪。
1. 系统设计时可以考虑在几个资源之间做些平衡比如用内存空间来换取CPU资源的使用。
### 压力测试Stress Testing
压力测试也是一种负载测试,不过它偏重的是在负载增加到超过系统设计预期后观察和验证系统的行为。当我们通过增加负载,对系统施压到超出设计期望的负载时,就能发现哪个模块或组件首先因超载而失败。这样我们就可以通过提升失败组件的性能来设计出更健壮、性能更优的系统。
相对于容量测试,压力测试的目的是为了暴露系统的问题,因此采用的负载不一定是真正的生产数据和客户请求。
## 总结
这一讲重点讲了几种性能测试。
<img src="https://static001.geekbang.org/resource/image/1c/73/1c5e4102c3f2b31b2f95ce9ee9851673.png" alt="">
在工作中和别人交流时,你一定还会听到各种不同叫法的性能测试。我从业多年的总体感觉就是,性能测试的种类太多,甚至对某一种测试怎么进行也众口纷纭。给人的感觉,就像古诗里面所说的,“乱花渐欲迷人眼”。
虽然各种性能测试叫法不一,但万变不离其宗,你只要主要抓住几点就行,比如分类的方式,流量的大小和测试的目的。
希望通过本讲的讨论,你能对不同的性能测试之间的区别更清楚一些了,以后工作交流和阅读文献时能搞清楚它们是什么种类的测试,从而对症下药,做好测试规划和合理的分析。
## 思考题
- 今天讲了这么多种测试,你平时用过几种?
- 对于没有用过的测试种类,你清楚了解它们的使用场景吗?
- 如果有的测试种类看起来还挺有用但自己没有试过,尝试着设计一个,并在工作中表现一下,把这种测试和其他已经有的测试种类的区别好好分析一下,让同事们和领导知道你才是性能测试专家!
欢迎你在留言区分享自己的思考,与我和其他同学一起讨论,也欢迎你把文章分享给自己的朋友。

View File

@@ -0,0 +1,119 @@
<audio id="audio" title="10 | 性能测试的规划和步骤:为什么性能测试不容易一蹴而就呢?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/bc/6f/bcf012e5227094132d74df187e338f6f.mp3"></audio>
你好,我是庄振运。
上一讲我们讲了不同类型的性能测试。今天我们来讲**如何规划一个性能测试和具体的执行步骤**。在规划任何一种性能测试时最重要的事情是搞清楚被测试的实体也就是SUTSystem Under Test对应的性能指标和度量以及期望的结果。在此基础上根据测试的类型来决定和规划具体的测试步骤然后执行测试最后再合理地分析测试的结果。
为方便描述,我们用下图来表示整个性能测试的过程,总共七个部分。
<img src="https://static001.geekbang.org/resource/image/72/38/72857508b6a54ce2da0467ce9249c138.png" alt="">
大体上分为前后两大部分。前面四个部分分别是决定SUT、决定性能指标、决定指标的度量、决定期望结果。后面三个部分是性能测试的规划、测试的执行和结果分析。这三个部分根据测试的结果或许需要重复多次。
## 搞清楚测试对象
性能测试当然首先要搞清楚测试对象。但说起来有意思,我看到过很多做性能测试的人,对“什么才是他的测试对象”这个问题糊里糊涂的。经常碰到的情况是,有些人做了一大堆测试,但后来发现搞错测试对象了,所以大量的工作白做了。
为什么会导致这样的误会呢?
因为一个被测试的系统往往是复杂的,包含多个子系统和模块。如果对测试的类型和规划没有搞透彻,就很容易搞不清真正的测试对象。
测试的对象一般叫SUTSystem Under Test它可以是一段代码、一个模块、一个子系统或者一个整个的系统。比如要测试一个在线互联网服务的性能那么这整个系统包括软件、硬件和网络都算是SUT。再比如SUT也可以是一个子系统比如运行在某台服务器上的一个进程。
搞清楚SUT的重要之处是让测试做到有的放矢。除了SUT本身其他所有的模块和构件在整个性能测试的过程中都不能有任何性能瓶颈。
比如测试一个在线服务,那么所使用的负载和流量模块就不能成为瓶颈。如果这一点不能得到保证,那么性能测试得出的数据和结论就是不正确的。拿上面的互联网服务来举个例子,如果性能测试中负责产生负载流量的模块成了瓶颈,一秒钟只能发出一千个请求,那么你测出的吞吐量最多也就每秒一千请求。这样的结果和结论显然是不对的。
## 决定测试的性能指标
搞清楚测试对象SUT之后下一步就是决定具体的性能指标。
对一个面向终端客户的SUT而言一般就是和客户直接相关的性能指标比如客户端到端的服务延迟。如果SUT是系统中的某个模块那么测试的指标有可能是资源的使用率比如CPU或者内存使用率。
平时用的最多的性能指标有三个,就是服务响应时间,服务吞吐量和资源利用率。这三个指标各有侧重,分别对应了终端客户、业务平台以及容量系统。通常,响应时间是用户关注的指标,吞吐量是业务关注的指标,资源利用率是系统关注的指标。
## 决定测试指标的度量
决定性能指标后还需要更加具体到统计上的度量。比如你关注的是平均值还是百分位数例如P99也或许是某个置信区间的大小。
举例来说对服务响应时间延迟的指标而言一般需要同时考虑平均值、中位数和几个高端的百分位数比如99百分位。
## 决定性能测试的期望结果
SUT和性能指标都确定了那么下一步就是决定**我们期望从测试中得出什么样的结论**比如是为了确认SUT的性能满足一定的指标呢还是只希望获取一些性能数据做参考。搞清楚了测试的期望结果才能决定什么样的测试结果是可以接受的什么样是不能接受的。
假设SUT是一个互联网服务测试指标是端到端的平均服务延迟。我们或许已经知道可以接受的平均服务延迟的最大值比如500毫秒。如果性能测试测出的结果显示平均服务延迟是600毫秒那么这个测试结果显然是负面的就是被测互联网服务不够好不能接受。如果只是想获取性能数据那么这个600毫秒就是测试结果。
再举几个更复杂一点的测试期望结果的例子:
- 当2000个用户同时访问网站时所有客户的P99响应时间不超过2秒
- 测试应用程序崩溃前可以处理的最大并行用户数;
- 测试同时读取/写入500条记录的数据库执行时间
- 在峰值负载条件下检查应用程序和数据库服务器的CPU和内存使用情况
- 验证应用程序在不同负载条件下,比如较低、正常、中等和重载条件下的响应时间。
## 性能测试的规划
一个成功的性能测试离不开具体的规划,比如如下的几个方面的重要内容,包括负载流量的特征、负载如何注入、测试的数据、黑盒还是白盒测试、测试的工具、测试的环境等,我们逐一说明。
**负载流量的特征**和我们上一讲讲过的测试类型直接相关。首先我们需要决定是用真正的生产环境的负载还是仿真的负载。
那么**负载如何注入**呢?负载流量即使已经确定用真正的生产负载,还需要继续决定几个问题:
- 是用实时的流量呢,还是用过去捕捉的流量来重新注入?
- 流量的大小,是完全模拟生产环境呢,还是加大负载。
- 如果不使用实时生产流量,那么如何注入呢?
很多情况下,直接采用开源的工具就够了,但有些情况下需要自己开发或者对开源工具进行二次开发。
很多负载需要操作数据,比如数据库查询。所以,我们就需要决定**测试的数据**,是用真正的用户数据还是仿真的数据。
测试选**黑盒**还是**白盒**呢黑盒就是不改变SUT完全做被动观察。白盒就是允许改变SUT比如在程序中间输出更多的性能日志信息等。白盒的问题就是改变了SUT的行为可能导致最终得到的数据失真。
市场上有各种各样的性能**测试工具**比如JMeter但是选择什么样的测试工具将取决于许多因素例如支持的协议类型、许可证成本、硬件要求、平台支持等。我们后面会有一讲专门讲各种工具。
配置一个合适的**测试环境**很重要,理想情况下,应该尽量用与生产平台相同的硬件、路由器配置、网络,甚至是网络背景流量等。不过值得说明的是,有时候我们会特意选取和生产环境不同的测试环境,比如当我们希望提高可重复性,降低测试环境的噪音;那么我们就会选取一个单独的不受干扰的环境来测试。
## 性能测试的执行
测试规划完毕后就是执行了,这个过程相对简单。
但是需要强调的是,**测试结果的可重复性非常重要**。性能测试和性能优化很多情况下是一个长期的行为,所以需要固定测试性能指标、测试负载、测试环境,这样才能客观反映性能的实际情况,也能展现出优化的效果。
很多性能测试比较复杂,所以不要期望一次测试就能成功让整个测试环境工作。经常需要实验好几次才能真正让整个测试环境搭配成功。
所以,复杂的性能测试需要多次迭代执行,一般有以下几种方式迭代:
1. 分步进行:把复杂的测试验证过程分成几步,一次验证一步,最后一步是整个完整的测试。这样的好处是每一步的问题都可以及早暴露,快速解决。
1. 先短时间测试,再长时间测试:有些测试需要执行很长时间,比如一周。如果一周后才发现测试过程有错误,那就浪费了一周时间。所以,为了避免浪费时间,会先进行短期测试,比如半小时。然后分析结果,来发现其中的问题。这样可以比较快速地纠正测试中的错误。
1. 模拟测试:在实际使用负载测试之前,先执行简单的负载测试以检查各种工具的正确性。
## 分析测试结果
测试完毕,就需要分析测试结果了。
如果对一次测试的结果我们不满意,我们就需要重新回到以前的步骤上,或者重新执行测试的步骤,或者重新规划测试的方法。
根据我的经验,几乎所有的性能测试,就算是看起来非常简单直白的测试,都需要反复进行多次,才能达到满意的效果。 所以如果发生这样的情况,你千万不要气馁。
为什么性能测试不容易一蹴而就呢?
这是因为任何测试,其实都依赖于很多其他模块,比如流量的产生、数据的注入、环境的搭建、干扰的排除、数据的收集、结果的稳定等,这些模块都不简单。所以寄希望于“毕其功于一役”,一次就完美地规划和执行一个测试,几乎是不可能的。
每一次测试完毕,我们都要认真分析一下结果,如果不满意,就需要看看如何改进。如果是测试方法不对,就需要重新规划。如果是环境不稳定,有干扰,那么就需要考虑如何消除干扰,净化测试环境。如果数据的收集不够多,就需要从测试模块中输出更多的信息。
## 总结
郑板桥在他的七言绝句《竹石》中说:“咬定青山不放松,立根原在破岩中“,赞扬竹子目标明确,基础扎实,而且百折不挠。
<img src="https://static001.geekbang.org/resource/image/a4/8c/a41d275dbe54a1034eb1de44b9cab38c.png" alt="">
我们做性能测试也是如此。只有条理分明,目标清楚,目的明确,规划仔细,执行得力,才能“千磨万击还坚劲,任尔东西南北风“。
这样的测试或许需要执行很多次,因为经常需要调整测试的方法,但不达目的,我们决不罢休。
## 思考题
假设你需要重复做一种性能测试但是你发现每次的测试结果都很不一样你可以想一想会有哪些原因呢举几个例子或许SUT服务器上面还在跑其他程序也或许注入的负载流量不稳定还有其他因素吗
欢迎你在留言区分享自己的思考,与我和其他同学一起讨论,也欢迎你把文章分享给自己的朋友。

View File

@@ -0,0 +1,124 @@
<audio id="audio" title="11 | 性能测试的工具:七大测试场景如何选择高质量的测试工具?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/e6/da/e6552235d7ffaf75cd1fe2e306cf0ada.mp3"></audio>
你好,我是庄振运。
我们在前面两讲讨论了如何进行性能测试的规划和设计。性能测试离不开合适的工具,那么这一讲,我们来讨论一下测试工具的分类和构成,并根据七个不同的测试场景,分别学习几个常用的高质量测试工具,尤其是开源的。
这七个测试场景分别是Web测试、系统测试、数据库测试、文件IO测试、存储测试、网络测试以及移动App测试。
我们应该尽量借助这些好用的工具,而不要自己去重新开发。
自己开发的话,费时费力不说,开发出来的工具也不见得会比这些工具好用。更重要的是,性能测试工具的开发和使用过程中,有很多需要注意的地方和容易陷入的坑,一不小心就会掉坑。我们下一讲就会讨论常见的坑。
而这些常用的工具已经经过很多人的努力和长时间的改进,在很多方面避免了容易出现的各种问题,所以尽量使用它们吧。
## 测试工具的分类
首先你必须认识到,性能测试工具是繁多的。之所以繁多,是因为每种工具适合的场合不同,所以它们各有特点。比如如下几个方面:
- 测试场景是针对Web环境、移动App、系统、数据库还是模块测试
- 测试类型:是基准测试还是峰值测试?
- 免费还是收费:开源工具一般都是免费的;但是很多收费工具也的确物有所值。
- 支持的协议比如是否支持HTTP协议、FTP协议等等。
- 支持的功能:比如并发性支持度,能否分析测试结果,能否录制性能测试脚本等。
## 测试工具的模块
要评价一个测试工具的优劣好坏,我们就需要知道测试工具的模块和测试的一般过程。
大规模性能测试的一般过程是通过录制、回放定制的脚本模拟多用户同时访问被测试系统SUT来产生负载压力同时监控并记录各种性能指标最后生成性能分析结果和报告从而完成性能测试的基本任务。
比照这个过程,一个稍微健全的测试工具都会包括以下的模块:
- 负载生成模块负责产生足够的流量负载。多少流量算足够这得根据测试类型和具体需求来定。如果测试类型是压力测试那么产生的流量一定要大到SUT不能处理的程度。
- 测试数据收集模块:负责获取测试的数据,包括具体的各种性能数据。这个收集可以是实时的,就是在测试进行之中收集;也可以是后期,等测试完成之后收集的。
- 结果分析和展示:有了大量的测试数据,就需要进行分析并展示。同样的,这个过程可以是实时的,也可以是等全部测试完成后进行。
- 资源监控模块测试过程中离不开对SUT和流量生成模块的实时资源监控目的是确保这两个模块运行正常。具体来说流量生成模块必须不能负载过量否则很可能产生的流量不够大。SUT也要确保运行还是正常的否则整个测试就失去意义了。
- 控制中心模块:测试者需要用这个模块和整个测试系统来交互,比如开始或停止测试,改变测试的各种参数等等。
这几个模块的关系我用下面这张图表示。
<img src="https://static001.geekbang.org/resource/image/1c/4f/1c4e724cff73f9595bb63b49a5cd3a4f.png" alt="">
## Web测试场景
我们先看第一个测试场景Web测试。这一场景的测试工具很多我们介绍几个。
**JMeter**是一款优秀而小巧精致的开源测试工具是用Java写的。JMeter安装简单使用方便所以很流行建议每个性能测试者都掌握它。熟练使用它在绝大多数场合都能大大提高测试效率。JMeter的测试是基于HTTP协议的所以最好对HTTP协议熟悉一些才能快速上手和理解里面的概念。
**LoadRunner**是HP公司的一款测试工具功能和资料都比较全也好用但不是开源的。它的组成模块都很强大比如分析模块中的AutoCorrelation向导。这个向导会自动整理所有的监控和诊断数据并找出导致性能降低的最主要的几个原因。这样就将性能测试结果转化为可处理的精确数据从而使开发团队大大减少了解决问题的时间。
**Locust**是基于Python的开源测试工具支持HTTP、HTTPS等协议。它的一个突出优点是可扩展性很好。
## 系统测试场景
这种场景下的测试工具很多,我主要介绍两个。
**UnixBench**是一个Unix系统比如Unix、BSD、Linux下的性能测试工具是开源的而且被普遍用于测试Linux系统主机的性能。这个工具可以测试很多模块和场景比如系统调用、读写、进程、图形化测试、2D、3D、管道、运算、C库等它的测试结果可以作为基准性能测试数据。
比如你可以用它测试从一个文件向另外一个文件传输数据的速率要求每次测试使用不同大小的缓冲区。再比如测试两个进程通过一个管道Pipe交换一个不断增大的整数的速度类似现实编程中的一些应用这个测试会首先创建一个子进程再和这个子进程进行双向的管道传输。它也可以测试进入和离开操作系统内核的开销即一次系统调用System Call的开销代价。
这是通过反复地调用 getpid 函数的小程序来进行的。
**Perf**是Linux下最普遍使用的性能分析工具功能强大全面俗称性能测试的“瑞士军刀”。比如Perf 可以对程序进行函数级别的采样,从而了解程序的性能瓶颈究竟在哪里。或者计算每个时钟周期内的指令数等等。
Perf的原理是使用特殊的计数器来进行性能统计。它既可以分析指定应用程序的性能问题也可以用来分析内核的性能问题所以可以全面理解应用程序中的性能瓶颈。
我个人建议每个关心性能的人都了解和学习一下Perf的使用。
## 数据库测试场景
数据库的测试工具也是汗牛充栋。
**SysBench**是一个容易使用的的开源多线程测试工具主要用于测试数据库性能比如MySQL Oracle和PostgreSQL但也可以测试CPU内存文件系统等性能。它的强项包括数据分析和展示模块多线程并发性比较好而且开销低。另外我们可以很容易地定制脚本来创建新的测试。
**mysqlslap**是MySQL自带的压力测试工具它可以轻松模拟出大量客户端同时操作数据库的情况。
## 文件IO和存储测试场景
对文件系统和存储系统的性能测试工具也有很多,比如**ioZone**可以测试不同操作系统中的文件系统的读写性能。比如可以测试不同IO读写方式下硬盘的性能。
Bonnie++是一个用来测试UNIX文件系统和磁盘性能的测试工具它可以通过一系列的简单测试来生成硬盘和文件系统的性能参数。这个工具很容易使用输出结果显示方面很不错。
如果你希望在Linux中很快地测试硬盘读写性能**dd**这个很有用的命令经常就够用了。这个工具就是用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。
## 网络测试场景
网络测试也有各种各样的工具。
**Netperf**是很不错的一个网络性能的测量工具主要针对基于TCP或UDP的传输。它有两种基本模式即批量数据传输bulk data transfer模式和请求/应答request/reponse模式我们可以根据应用的不同来选择不同模式。
测试结果所反映的,是两个系统之间发送和接受数据的速度和效率,即一个系统能够以多快的速度向另一个系统发送数据,以及后者能够以多快的速度接收数据。
**Iperf**可以测试最大TCP和UDP带宽性能具有多种参数和UDP特性可以根据需要调整可以报告带宽、延迟抖动和数据包丢失。这个工具使用起来很简单一条命令行就可以。比如如下的测试“采用UDP协议以100Mbps的数据发送速率从本机到服务器192.168.1.1作上传带宽测试测试时间为120秒”或者“以50Mbps的发送速率同时向服务器端发起100个连接线程”。
## 移动App测试场景
移动App测试的性能指标主要是内存、CPU、电量使用、启动时长、显示帧率、网络流量等。 针对App的性能测试工具和平台可以按照两种方式分类。
第一种分类是根据**线下还是线上**。线下App性能测试主要依靠传统测试手段和方法比如不同的版本框架等等都需要进行App性能测试。 线上测试算是场景化测试主要针对大规模或者动态环境让App在特定场合和特别条件下更精准地衡量App的核心性能。
另外一种分类方式是**平台生态系统**现在主要有安卓Android和iOS。有的测试工具可以兼容多个平台比如**Appium**就是一个可以同时支持安卓和iOS的测试框架的工具功能强大。
对Android的测试工具常用的有**adb**Android Debug Bridge和**Monkey**。Monkey是Android SDK自带的测试工具。Monkey的意思是猴子 顾名思义,就是在电脑面前乱敲键盘在测试。 在测试过程中会向系统发送伪随机的用户事件流如按键输入、触摸屏输入、手势输入等对App进行压力测试也有日志输出。
对iOS App的测试工具也很多比如XCTest、Frank、KIF等等这里就不展开了。
## 总结
古人说:“工欲善其事,必先利其器”。业界已经有很多好用的工具,一般都能满足大多数场合的测试要求,会让我们的测试工作如虎添翼。
<img src="https://static001.geekbang.org/resource/image/fd/47/fdc924cbf4fe1122ff2da78e4cccdd47.png" alt="">
虽然有些环境下我们经常倾向于自己开发某些工具,但是往往会花费很多时间,而且很容易陷入各种各样的坑中,因此尽量避免自己开发。
这一讲介绍的几款工具适用于不同的场合,如果你能合理运用它们,应该会取得事半功倍的效果。
## 思考题
- 你曾经用过什么样的性能测试工具?
- 为什么会选择这些工具,而不是其他的工具?
- 你使用的测试工具有什么优点和缺点?
- 你是怎么克服它的缺点的?
欢迎你在留言区分享自己的思考,与我和其他同学一起讨论,也欢迎你把文章分享给自己的朋友。

View File

@@ -0,0 +1,154 @@
<audio id="audio" title="12 | 九条性能测试的经验和教训:如何保证测试结果可靠且可重复?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/4b/57/4b29e641c379c76f56519d06bb404e57.mp3"></audio>
你好,我是庄振运。
上一讲我们介绍了十几种常用的性能测试工具。我们知道,性能测试的一个关键是保证测试结果可靠、可重复,否则就没有意义。所以,我们今天来学习一下进行性能测试时,这方面的经验和教训。
根据以前做过的相关工作,我总结了九条这样的经验和教训。按照逻辑时间顺序,我将它们大体上分成三大类别,就是测试前的规划、测试中的变化和测试后的结果分析;每一类又有三条要点。
<img src="https://static001.geekbang.org/resource/image/ee/a5/eee41a2f022ed7c88ea2a31c5b4157a5.png" alt="">
## 测试规划
三大类别的第一类别是测试规划,我们先来说说测试规划时要注意的三条要点。
### 1.详细记录测试环境和测试过程
做每个性能测试时,测试的环境至关重要。这里的环境包括软件硬件、操作系统、测试的负载、使用的数据等等。
测试的环境不同,性能测试的结果可能会迥异。除了测试环境,其它几个因素比如测试的过程,包括步骤和配置的改变也有相似的重要性。所以,我们每次测试都要把测试环境和测试过程记录下来,为将来分析数据做参考。
这些测试环境信息包括什么呢?大体上是操作系统和程序的版本号,以及各种软件参数的设置等等。
记录测试环境的目的是为了以后的各种分析。比如我们如果发现两次测试结果不匹配,需要找到不匹配的原因,那么这些测试环境就是相当关键的信息。如果两次测试结果的不同是因为软件配置不同导致的,那么根据记录的测试环境信息,我们就很容易根因出来。
至于如何记录,我们可以去手工去记录,但最好是自动记录,因为手工记录既费时费力,又容易出错。如果我们知道常用的环境配置的路径,可以很方便的写个程序来自动记录。或者依靠能自动记录配置的软件也可以。
### 2.快速地复位测试环境
有时候性能测试需要重复进行多次,那么就需要在每一次测试后,能够有快速“复位”到初始测试环境的机制。这个复位机制越简单有效越好,最好能达到所谓“一键复位”的程度,从而最大限度地降低手工复位的工作量。
复位的具体内容和方式要根据性能测试的情况而定,这就要分析一下在每个测试过程中,哪些子系统的配置和参数被改动或者影响了。
虽然理论上说,我们只需要恢复那些会影响测试结果的配置和参数,但是由于系统的复杂性,有些乍看起来不会影响测试结果的参数,其实或多或少也会影响测试结果。所以一般来讲,我们会**把所有的配置和参数都恢复一下**。环境复位的具体方式包括重新拷贝文件、重置配置参数、清空各种缓存等。
举个具体例子,如果是测试一个存储系统的性能,比如硬盘的性能。如果测试过程中写入了大量数据到存储系统,那么测试完毕,恢复环境的时候,就需要删掉这些数据,以便使被测系统回到初始状态。
再举个类似的例子,如果是测试一个数据库的性能,那么测试过程可能发出了很多查询请求。因为数据库经常会缓存各种情况和结果,所以在恢复测试环境时,不要忘记把缓存也清空。
一个现代计算机系统中往往有很多种缓存比如数据库缓存、文件系统缓存、存储缓存比如SAN等。不同种类的缓存自然有不同的清空方式。对于数据库缓存在每个测试之前可以用命令行来刷新数据库缓存如果数据库不提供这样的命令则需要重新启动数据库。对于文件系统缓存一般需要重新启动服务器。对于SAN缓存可以考虑在测试期间减少甚至关闭缓存或者用大量的随机数据来“污染”缓存。
### 3.足够的负载请求和数据
性能测试需要流量负载以及相关的数据,我们需要特别注意保证它们的多样化和代表性。否则测试结果会严重失真。
当使用相同的测试数据进行重复测试时,如果负载请求不够大,那么各种缓存可能会严重影响结果。
如何识别缓存的影响呢?
各级缓存系统都有相应的统计指标和命令比如文件系统缓存和SAN缓存中的缓存命中率就可以通过统计信息中报告的延迟并且结合经验来识别。举例来说如果一个随机8KB或16KB数据的对硬盘的读写测量出的延迟不到1毫秒那就实在是“太快”了快得让人不敢相信可以肯定它是命中某种缓存了。
除了合理清空缓存外,更有效地方式是保证测试时间足够长、测试的负载请求足够多和数据足够多样化,从而最大限度地减少或者掩盖缓存等其他因素的影响。
## 测试进行
测试规划之后,我们就要关注测试中的变化了。
### 1.性能数据日志要适当输出
性能测试过程中也需要实时输出有关的性能数据和日志比如CPU使用率数据。这些数据对于测试完成后的分析至关重要。
输出的数据和日志最好保存起来,以方便后期处理/重新处理。比如执行过很多不同参数配置的测试之后,我们经常需要进行测试之间的比较,这时候就需要仔细检查以前输出的日志了。
输出数据的多少也需要注意,虽然我们希望尽量多地输出,但是也要意识到,太多的输出有时候会起反作用。
- 存储的开销:可以用压缩存储来解决。
- 数据处理时间的开销:注意压缩和解压缩也要花时间。
- 可能影响性能测试的结果:有时候因为某些原因,日志输出会影响被测系统的性能,比如往一个文件写入日志,可能会导致系统的暂停,从而影响测试的结果(这个我们下一讲会详细剖析)。
### 2.测试环境要稳定
性能测试的环境在测试进行过程中,以及重复测试时一定要保持稳定和一致,否则测试结果就不可靠或者不能重复。
比如一个测试进行中,背景流量的负载产生了剧烈变化,导致被测系统的延迟增加。假如这个背景流量变化不是预期产生在测试规划之内的,就会造成测试结果失真。
类似的,如果测试过程中有不可控的因素,造成每次重复测试结果都不同,那这样的测试就不可靠。无论测试结果好坏,都不能用来作出有用的结论。
一般的解决方案,是尽量在一个独立无干扰的环境中进行测试,加上每次测试都准确地恢复测试环境,就能最大限度地保证测试环境的稳定。
### 3.一次调一个参数的利弊
在性能调优测试中,就是通过实验来找出系统的最优配置。
对这种测试,我们经常听到的经验是,“一次只调一个参数,通过对比实验,就能知道这个参数的最佳值”。你觉得这个经验对吗?
我们先看这个经验的出发点。性能调优过程中有很多可调参数和配置,互相之间的影响不清楚,因此不宜对系统的各种参数进行随意的改动。应该以基本参考设置为基础,逐次根据实际测试结果进行优化,一次只对某个领域进行性能调优,并且每次只改动一个设置和参数,避免其他参数和相关因素的干扰。
这个经验有它的道理,但我觉得这样做既对也不对,你不能盲从,否则就会错过最优配置的机会。
我举个生活中的例子来说明。假设有一个装水的木桶,这个木桶由多块可调整高度的木条组成。假设这些木条的初始高度不一,我们的目的是找到一个木条高度组合,从而实现最大的装水量。这个问题看起来很简单,根据木桶定律,就是把每块木条都调到最高嘛。
<img src="https://static001.geekbang.org/resource/image/c9/e7/c91e6cbdd7b63b27a0d1f0bf9bd5ace7.png" alt="">
我们假设这个木桶是我们的被测系统,每块木条就是一个参数。再假设我们对木条之间的关系不清楚。如果一次只调整一个参数,然后实验测试装水量。因为木桶装水量取决于高度最低的木条,我们或许会得出结论——只有那块最低木条值得调,其他木条的高度都不重要。
这种结论的结果就是把最低木条调高,比如调到最高。那么这个所谓的“最优系统”,也就是整个木桶的装水量取决于新的最低木条,也就是原来木桶中高度次低的那个木条。
我们很容易看出,如果一次调整多个木条,那么我们就会很快地找出一个更优的系统,也就是一个装水更多的木桶。
## 结果分析
测试后的结果分析也是需要你关注的重点,三条经验如下:
### 1.根因分析要由易到难
如果在性能测试过程中需要查找性能瓶颈,查找的过程一定要由易到难逐步排查。因为参考我们学过的帕累托法则,从最明显的性能瓶颈来开始,往往可以事半功倍。
首先从最常见的几种资源和几个指标查起比如CPU使用率、存储IO繁忙度、内存大小、网络发送和接收速度等。
进一步的分析就可以针对不太明显的资源比如内存带宽缓存击中率线程加锁解锁等从而过渡到应用程序和系统的一些配置参数。这些配置参数包括应用服务器及中间件操作系统瓶颈数据库、WEB服务器的配置还有应用业务瓶颈比如SQL语句、数据库设计、业务逻辑、算法、数据等。
### 2.几种测试最好互相验证
各种性能测试工具和测试手段都有自己的局限性或缺陷,从而可能会造成测试结果出现偏差。所以,如果条件和时间允许,最好使用几种不同测试工具或手段,分别进行独立的进行测试,并将结果相互比较和验证。
如果几种测试比较后结果相似,那么皆大欢喜。
否则就需要进行深入比较分析,弄明白造成结果不同的原因。分析以后,如果能够清楚地了解根因并作出合理解释,那么很多时候就够了,可以止于此。最后形成结论时,只要稍加有针对性地说明就可以。
### 3.测试结果和生产环境比较
如果性能测试是在非生产环境中进行的,那么得出的测试结果或许会和生产环境大相径庭。如果我们测试的目的是尽量和生产环境一致,就需要仔细审查每个测试的环节,包括测试环境和测试流程。
假如非生产环境的测试结果和生产环境的测量不同,很多情况下是由于测试环境不同导致,尤其要注意的是网络环境的差异。
比如测试的环境是在局域网而真正的生产环境是无线网或者4G那么可以肯定这样的局域网测试没有什么意义。网络差异的影响经常会大大超过很多人的预期因为实际的生产环境还牵扯很多上层协议和背景流量比如HTTP协议。
假设4G用户在网络层或者链路层上相对局域网而言只是多了30毫秒的延迟。在Web服务器中等负载的情况下这几十毫秒的链路层延迟就可能导致应用层响应时间增加惊人的几十秒延迟。
对网络环境这点,最理想的解决方式当然是在生产环境进行测试。如果实现这点有困难,那么可以考虑使用一定的网络仿真,来模拟真实生产环境。
除了网络环境的影响真实客户的操作流程也可能造成测量结果的不同。比如一个真正的Web用户或者APP用户在访问我们的系统时往往会有思考或者阅读时间所以真实世界的用户不太会在1秒钟内发出背对背的好几个页面请求。对于这种情况的差异可以通过人为地添加停顿来模拟思考时间。
现在很多测试工具都支持这种思考时间的引入。比如使用JMeter可以使用高斯随机计时器Gaussian Random Timer来模拟现实世界中的用户以随机方式和页面进行交互。
## 总结
<img src="https://static001.geekbang.org/resource/image/eb/c0/eb79090925a67c93acc09ae2efed0cc0.png" alt="">
当年毛主席给彭德怀写过几句诗:
山高路远坑深,<br>
大军纵横驰奔。<br>
谁敢横刀立马?<br>
唯我彭大将军。
打仗有很多坑,做性能工作也有很多坑。我们要把性能测试的工作做好,本身就不容易。山高路远都不在乎,但一定要注意其中的陷阱。
所以只有不断地学习别人总结的经验,吸取别人的教训,解决测试的各种挑战,才能得出可靠,可重复并且有意义的性能测试结果。
## 思考题
回想一下你做过的性能测试,有没有踩过今天介绍的几个坑?踩过之后,是怎么防止以后不再踩同样的坑的?对没有踩过的坑,你有没有方法避免以后中招呢?
欢迎你在留言区分享自己的思考,与我和其他同学一起讨论,也欢迎你把文章分享给自己的朋友。

View File

@@ -0,0 +1,126 @@
<audio id="audio" title="13 | 性能测试的工程集成:如何与产品开发和运维业务有机集成?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/ea/69/ead8315502687b20efd01abfff216969.mp3"></audio>
你好,我是庄振运。
前面几讲,我们讨论了性能测试的几个方面,包括测试的种类、测试的规划、工具以及经验和教训。
今天我们讨论性能测试如何和其他系统进行智能集成,也就是如何让**性能测试**这一工作从单独的、一次性的、手工发起的、传统的人工操作,进化成一个和开发及运维过程相结合的、持续的、自动重复执行的智能操作。
## 性能测试模式的演化
性能测试作为IT公司的一种重要工作它的工作模式正在从传统的手工模式不断进化成智能集成的自动模式。
这样的演化主要归功于这些年互联网技术的进步和业务需求的提高,包括数据量的加大和业务的日益复杂化、客户需求的多元化、公司业务规模的扩大,以及人工智能和机器学习的不断成熟。
那么,性能测试的模式进化表现在哪些方面呢?主要有四个方面,如下图所示:
<img src="https://static001.geekbang.org/resource/image/18/df/189133714d4ed913957d36667dab2bdf.png" alt="">
1.从**独立的操作**演化成和其他系统(比如开发和运维)的**有机集成**。
公司中很多业务都和性能测试有关,尤其是产品开发和系统运维业务。性能测试需要和这些业务紧密结合,从而使相关工作的效率极大提高。
2.从一次次的**单独执行**演化成**持续而重复的执行**。
从开发角度来看,一个产品的程序代码会不断被开发和增强,包括加入新的功能和修补发现的错误。每次代码改变都需要进行性能测试,以确保程序面对客户的端到端性能和资源利用效率没有变低。从运维角度来看,公司的产品系统也需要持续地进行性能测试,以尽早发现可能的问题。
3.从**手工进行**测试演化成**自动化**的测试。
每当需要进行性能测试的时候,系统越来越需要自动触发,并按照既定规则来开始测试。测试完成后也需要自动进行分析,并根据分析的结果继续进行后面的定义好的步骤。整个过程最好不需要测试人员的人工参与,以降低运营成本并减少人为错误。
4.从常规的**人工操作**演化成基于人工智能AI和机器学习ML的**智能操作**。
数据量的变大让有效的机器学习成为可能。同时伴随着人工智能技术的不断成熟,传统常规的性能测试一步步地走向智能的自动性能优化。
## 和产品开发的系统集成
性能测试和产品开发密切相关,我用下面这张图片表示它们之间的关系。我分成两部分讲,先讲和产品开发的系统集成。
<img src="https://static001.geekbang.org/resource/image/b1/c7/b1a78241835c50a5ec0754fabfbfd9c7.png" alt="">
性能测试和产品开发的集成也是所谓“持续集成”Continuous Integration的一部分。
什么是“持续集成”呢?
这个概念已经在软件开发领域存在很多年了本来是为了配合敏捷开发Agile Developement的速度和效率而产生的是把源代码管理、代码检查、程序编译、性能和功能测试、产品部署等一系列操作整合在一起的概念和工具。
怎么才叫“持续”呢?
就是从程序员提交了源码开始,相关工具就会自动进行编译、测试等一系列运作,并将结果反馈给程序员。这样,提交代码的程序员很快就会知道刚刚提交的代码有没有问题。
可能发生的问题有很多种,包括编译错误、整个程序不能运作、能编译运行但是整体性能变差等等。如果发现这样的问题,程序员和团队就可以迅速进行改正,不必等到开发周期后期才寻找和修复缺陷。
什么叫“集成”?
就是上述一套操作都是有相应工具支持的,几个工具又集成在一起,构成一个完整的系统。
持续集成包括两个重要阶段:持续交付和持续部署。我们先说一下持续交付。
**持续交付**Continuous delivery指的是开发人员的每一次代码提交都会自动地编译并且运行已经定义好的测试程序。
测试程序里面就包括性能测试和结果分析。如果分析的结果确认这次代码提交没有性能问题,就成功接受这次提交。否则,就会采取措施通知代码提交者去修正代码;并重复这个过程,直到通过。
**持续部署**Continuous deployment是持续交付的下一步指的是代码通过评审以后自动部署到真正的生产环境。
持续部署的目标是,代码在任何时刻都是可部署的,并且是可以进入生产阶段的。持续部署的前提是能自动化完成测试、构建、部署等步骤。同时,如果一旦部署了的版本发生不能接受的问题,就需要回滚到上一个版本。这个回滚的过程也需要简单方便,否则会造成非常大的混乱。
持续集成的价值何在?
持续集成的价值主要有几点:降低代码开发风险,及早发现集成错误,减少手动测试过程,快速生成测试结果,提高程序员和开发团队的安全感。同时,频繁的提交代码,也会鼓励和促使开发人员创建模块化和低复杂性的代码。
### 工具集
支持持续集成的工具有很多按照领域分可以有下面几大类代码版本管理、代码检查、编译连接、功能测试、性能测试、性能分析、代码覆盖率、结果展示等。有些流行的持续集成服务器可以整合这些工具或功能比如Jenkins、CruiseControl、Travis等。
我举一个完整持续集成的工具例子。比如一个Java开发团队在开发某项目时用了如下的一系列工具
- 用JStyle来分析Java源代码
- 用Ant 构建运行JUnit来进行简单的功能测试
- 用DbUnit 执行长时间的数据库组件测试
- 用JUnitPerf来进行负载和压力测试
- 用JProfiler来进行全功能的代码性能剖析
- 用 Selenium运行基于 Web 的功能测试
- 用 Cobertura测量代码覆盖率
- 用 CruiseControl 作为服务器来管理持续集成
## 和运维业务的系统集成
讲完了性能测试和开发过程的集成,我们接着谈谈和运维业务的系统集成。
广义上来讲,性能工作也是运维的一部分,包括性能测试、性能分析和性能优化。但是,如果把性能工作和其他运维业务分开来看,它就需要和其他运维业务有机而智能地集成。
运维业务的一个趋势是智能化。
智能化的原因是互联网数据量的变大运维业务的多样化和复杂化以及对运维服务质量要求的提高比如低成本、低延迟、高防范。这样一来很多传统的运维技术和解决方案已经不能满足当前运维所需。另一方面机器学习ML和 人工智能AI技术在飞速发展这就推生了智能运维AIOpsArtificial Intelligence for IT Operations这是运维未来发展的必然趋势。
在这样一个趋势里,运维就需要和性能测试的过程紧密集成。
一是通过持续而智能的性能测试,能及时发现已有的和将来可能会发生的性能问题,从而快速修复和及时预防。比如,根据性能测试的结果,可能会发现在不久的将来,整个系统的某项资源会用光,有可能导致系统挂掉。这种情况,我们就可以提前采取相应的措施,来避免这一问题的发生。
二是通过不同种类的性能测试,来找出最佳的解决方案。或许,对有些简单的性能问题,我们能很容易发现和解决,但对很多复杂的性能问题,就比较难找出原因和确定最优方案。要找出最主要的性能问题根因,经常需要进一步的性能测试。即使找到根因,现代互联网服务产品的子模块之间依存度很高,互相的交互多而复杂。那么什么样的解决方案才是效果最好,最容易实现的的,往往需要进行进一步测试来验证。
性能测试和运维的集成必须有两个特点:**有机**和**自动**。
不管是性能衡量、问题预测、根因分析还是性能优化,人工去执行都非常费时费力,从而不可取。唯一可行的就是借助于人工智能来尽量自动化。除了持续自动地进行性能测试,发现性能问题还需要进行自动分析,找出问题后也要执行自动调整优化。
我们的目标是**让性能测试和运维业务进行智能的有机集成**,其中的智能来自于对大数据的分析和机器学习。
无论是本业务系统的历史数据,还是其他业务系统的数据,甚至是业界其他公司的数据和经验,都是机器学习的对象和分析的基础。同时,我们还需要注入适当的知识和规则,来帮助这一套集成的持续优化。
在这一过程中,数据的采集和整理是一切的基础。公司层面需要全方位,实时、多维度、全量地对各种运维数据采集、整理和存储。这里的运维数据包括基础架构的机器监控数据,内网和外网的网络数据,公司业务流量数据,工单系统数据,日志监控数据等。这些数据需要有统一而合理的接口,以方便访问。
## 总结
性能测试虽然有很多讲究和注意的地方,但它本身也是作为整个公司业务的一个子系统而存在的。我们需要把它和其他几个子系统,尤其是产品开发子系统和运维子系统有机地整合集成起来,让这几个子系统之间的操作“浑然天成”,才能获取整个公司业务的最大收益。
<img src="https://static001.geekbang.org/resource/image/45/16/4507f2890c2a8a050b4e2c83f8714216.png" alt="">
白居易的《长恨歌》有两句:“在天愿作比翼鸟,在地愿为连理枝”,期盼的是一种比翼齐飞,一种同心同德。
这种期盼用在这一讲的子系统集成也挺合适。性能测试和产品开发子系统的集成,可以使得开发过程的迭代更快、更高效,并保证代码质量。性能测试和运维子系统的集成,可以让整个程序和业务保持高性能运转,提高公司业务质量和公司营收。
## 思考题
你现在的开发环境中有没有整合这样的自动测试系统?如果没有,你觉得值得考虑一下吗?如果你能从无到有的搭建一个这样的系统,你老板会不会对你刮目相看?
欢迎你在留言区分享自己的思考,与我和其他同学一起讨论,也欢迎你把文章分享给自己的朋友。