如何做好压测

压测的目标是什么?

压测的目标有两个:

  1. 通过对模块的压测,找到模块的性能瓶颈,分析其资源耗用合理性、架构可扩展性,找到优化方向。
  2. 通过对链路的压测,找到链路的性能瓶颈,回答线上资源容量。

压测的技能栈有什么?

压测的技能栈要求非常广泛,整体来说,需要具备这些技能:

  1. 测试人员的思维习惯和方法论。找到合适的测试模型,并准备好/管理好这些数据。
  2. 运维人员的对系统的认识。能够根据需要配置合适的系统资源,能够一定程度上进行系统问题排查。
  3. 开发人员的开发能力。往往在数据准备过程、测试过程中,需要有较多的工具类开发。
  4. 数据分析人员的分析能力。在数据准备和压测过程中,需要提前预规划各类指标与数据,用于分析系统状态,有时需要比较强的数据分析能力。
  5. 对业务系统熟悉。能够在一定程度上进行问题排查。
  6. 对常用的中间件熟悉。能够进行常规中间件的性能评估与异常分析,例如 kafkamongodbmysqlredis 等。

具体的技能,需要根据业务情况而定。但也有一些通用的技能:

  1. 工作规划能力。由于压测的工作往往十分庞杂,因此要能规划好工作内容,各个阶段的安排要合理。
  2. 文档书写能力。压测的过程十分庞杂,因此每个阶段的工作都应该有比较好的记录和分析,用于指导下一环节的工作。常写的文档包括: 1. 压测规划书 2. 压测结果记录 3. 压测分析报告 4. 系统结构分析图。
  3. 沟通能力。由于压测涉及到的范围很广,尤其是一个比较大的链路压测时,压测人员基本无法对整个系统有较强的掌控能力,需要 1. 市场/运营人员 2. 模块开发负责人员 3. 运维人员 的参与,因此协调这些人员的工作就会十分重要。

压测的形态是怎样的?

  1. 压测可以分为基准测试和链路测试。基准测试是对单个模块的压测。链路压测是对一条业务流程的压测。
  2. 对于一个常规的压测流程,应当先对模块进行基准测试,在得到每个模块的性能指标后,再进行链路压测。

压测的结论有哪些?

  1. 回答压测的模型是怎样的,说明为什么选择这样的压测模型
  2. 回答在目标QPS下,当前的系统瓶颈是什么
  3. 给出压测过程中发现的不合理之处

压测的流程是怎样的?

  1. 分析业务形态,系统形态
  2. 根据业务需求,确定合适的压测模型
  3. 准备压测环境
  4. 准备压测数据、压测工具
  5. 确定系统可观测性,确定测试终止条件
  6. 压测执行,处理过程中的问题
  7. 根据压测过程,形成压测报告
  8. 根据压测报告进行分析,形成分析报告

压测的工程化实践

业务系统的压测(从链路来看),往往可以分为这两类:

  1. http 请求
  2. 其他类 TCP 请求

由于业务系统主要面向用户,因此对于 http 请求的压测是最多的,这也是市场上生态最好的类型。常规的例如 jmeterlocustk6PTSloadrunner ,这是用于系统性压测的工具。另外,在开发人员保障的性能测试中,abwrkgo-stress-testing 这几个工具被经常使用,用于快速验证。

其他类的请求相对较少,例如 rpcwebsocket 这类。即使有一些实现,但真正结合到业务中时,会发现各种不满足需求。实际上,这类测试最好还是自己根据业务情况写项目实现。

压测项目是一个比较具有通用性的项目,因此可以考虑将其平台化,但目前来看,在最通用的 http 压测上,是比较容易平台化的,市场上也有很多,例如上面提到的 jmeterloadrunner 等。不过,市面上的这类工具基本都是用来进行 压力管理 的,而测试计划、测试脚本、测试报告 等方面的管理是比较弱的,因此,也有企业在开始做云端化的压测管理平台,比如 metersphere,现在做得也基本可用了。

对于接口类的测试,通用性是非常强的,例如和 接口管理 结合,可以实现类似于:自动化生成测试用例流量录制测试跟踪(bug管理等)基于接口测试的性能测试等等。实际上,这些功能 metersphere 也支持了,不过有部分是企业版的(如项目管理平台集成)。

对于接口类测试,我们当前使用的是自己开发的一个项目 super-apitest ,这个项目的最大亮点在于 基于json的模板化用例 ,这点可以认为和 jmeter 的 jmx 格式类比,不过基于 json 的格式,对开发者更加友好。

现在这个项目仅有一些简单的功能,例如适配了简单的触发界面、结果报告、结果通知,但想要真正做到平台化,还有非常长的路要走。

当前来看,这个项目可以在一定程度上进行平台化,主要的功能点有 3 个:

  1. 支持所有用例使用数据库管理 => 一切演进的前提
  2. 支持测试用例录制 => 极大简化用例生成方式
  3. 支持测试用例通过率统计 => 极大增强测试跟踪

如果做到这 3 点,这个接口测试平台已经基本可用了。

对于其他类型的功能测试,主要包括

  1. 工具库的单测和覆盖度测试
  2. 模块的功能测试
  3. 非 http 类的接口测试 (例如 rpc、ws、异步消息)

这些测试基本不具备很好的通用性,平台化的效率比较低,对于这类测试,平台的作用其实主要有:

  1. 测试触发
  2. 测试用例元信息管理
  3. 测试结果展示

基于此,可以认为,平台仅需要提供特定的接口,由各测试项目自行实现测试触发、测试结果反馈即可。

对于性能测试,如果全为 http 类接口,则平台化的效率较高,可以直接和 接口测试 模块相结合,由接口测试提供用例,由性能测试模块提供压测控制。

同样,对于非 http 类接口而言,性能测试的通用性就比较弱了,比如各个项目的性能。那么平台依然可以提供测试管理接口,由平台来做触发和结果采集,实际的测试执行由各业务项目自行处理。

功能测试和性能测试的关系

功能测试的目的在于保证功能的正确性,有时会有比较复杂的校验逻辑,测试用例集的组织形式经常为一个功能。

性能测试的目的在于摸清一些功能或场景的最大(合适)并发度,用于排查性能瓶颈和做线上资源容量规划,校验逻辑往往比较轻量,着重在压力 ,测试用例集的组织形式尝尝是一系列场景,并且十分关注各场景的比例,目的模拟真实用户的请求。

压测项目的价值有多大

根据压测的两大目标来看: 1. 发现系统瓶颈,提供优化建议 2. 回答线上容量问题

对于第 1 点,这是项目开发时需要的,例如开发一个通用的库,需要根据压测的结果进行优化。实际上,这是任何一个开发工程师都需要具备的能力,尤其是写中间件的工程师。

这种情况下,压测基本上是驱动这个项目进化的源动力之一。也是业务方评判这个项目的优劣及适用性的一个很重要的标准,业界流行的 rediskafkamongomysql等这类中间件,都是直接在发行版中自带 benchmark 工具。

对于第 2 个问题,大多数时候需要链路压测。最常见的系统压测是基于 http 这类 “request/response” 的,而这也是测试工程师最常接触的。目标在于找到整个链路的性能峰值。

毫无疑问,在项目开发过程中,我们需要回答第 1 个问题,而往往这个问题需要研发工程师自己回答。但从实际的情况来看,对于大多数业务场景,这类问题是比较基础的问题,如果项目中有比较高级一些的研发工程师在技术评审时下点功夫,基本就能将这些问题扼杀在摇篮里。

也就意味着,业务系统做这类压测,原因往往有两个: 1. 技术管理体系不成熟,代码质量得不到保障。 2. 跟其他业务有所关联,需要自证。

如果要回答第 2 个问题,就需要链路压测,这也是最被大家所熟悉的压测,这类压测往往需要一个团队来执行,主要包含: 1. 测试工程师 2. 运维工程师 3. 研发工程师 4. 业务人员(运营/产品)。 在新项目上线、大促活动等情况下,一般需要做这类测试,用于保障线上不会被打垮。

业界做的比较好的容量是怎样的

根据一些公开资料,有了解到使用机器学习的方式,得出各条件下对于机器资源的需求量。机器学习的来源,一方面是通过多次(很多)压测得到,另一方面,是通过线上实际数据反馈进行修正。

这样一套容量的机器学习方案确实是一个不错的选择,尤其是对于业务较多的企业,还是有不错的收益,例如阿里的本地生活就有这么一套。

性能保障的职责

  1. 由测试人员
  2. 由运维人员(sre)
  3. 由开发人员
  4. 由架构师

对于常规的 http 请求的压测,可以由测试人员负责,凭借测试人员对业务场景的理解,可以构造出符合需求的测试脚本,再使用特定的压测工具,则可进行压测,压测的结果也比较清晰,可以直接交给相关项目的开发人员去进行接口优化。

针对特殊项目的压测,和普通意义上我们认为的测试工程师所做的工作不太一样,常规认为的测试工程师,大多凭借对业务场景的理解,加上对测试(功能/性能)工具的掌握,能做针对业务场景的测试/压测。这种项目的性能测试需要对这个项目本身比较熟悉,往往需要自行开发一些压测的工具来进行压测,从上述描述的测试工程师所擅长的技能来看,不能很好匹配。

对于链路压测,一般来说需要准备的内容比较复杂,包含 压测目标确定环境准备压测场景构建压测脚本压测过程控制项目配置/环境配置调整压测资源监控压测报告压测结果分析 等一系列环节。

这些环节过于复杂,对于任意一个工程师而言,都是几乎无法完成的。因此,往往需要一个团队来配合。团队内的分工大致如下:

  1. 业务人员(产品/运营),负责压测目标的确定(业务侧视角)。
  2. 测试人员,负责压测场景梳理、压测数据准备(协同研发人员)、压测执行、压测结果收集、压测报告
  3. 研发人员,负责standby问题排查、环境配置调整
  4. 运维人员,负责环境准备、协助排查资源问题
  5. 架构师/高级开发人员,负责压测结果报告分析、优化方案

文档直通车