如何做好压测
压测的目标是什么?
压测的目标有两个:
- 通过对模块的压测,找到模块的性能瓶颈,分析其资源耗用合理性、架构可扩展性,找到优化方向。
- 通过对链路的压测,找到链路的性能瓶颈,回答线上资源容量。
压测的技能栈有什么?
压测的技能栈要求非常广泛,整体来说,需要具备这些技能:
- 测试人员的思维习惯和方法论。找到合适的测试模型,并准备好/管理好这些数据。
- 运维人员的对系统的认识。能够根据需要配置合适的系统资源,能够一定程度上进行系统问题排查。
- 开发人员的开发能力。往往在数据准备过程、测试过程中,需要有较多的工具类开发。
- 数据分析人员的分析能力。在数据准备和压测过程中,需要提前预规划各类指标与数据,用于分析系统状态,有时需要比较强的数据分析能力。
- 对业务系统熟悉。能够在一定程度上进行问题排查。
- 对常用的中间件熟悉。能够进行常规中间件的性能评估与异常分析,例如
kafka
、mongodb
、mysql
、redis
等。
具体的技能,需要根据业务情况而定。但也有一些通用的技能:
- 工作规划能力。由于压测的工作往往十分庞杂,因此要能规划好工作内容,各个阶段的安排要合理。
- 文档书写能力。压测的过程十分庞杂,因此每个阶段的工作都应该有比较好的记录和分析,用于指导下一环节的工作。常写的文档包括: 1. 压测规划书 2. 压测结果记录 3. 压测分析报告 4. 系统结构分析图。
- 沟通能力。由于压测涉及到的范围很广,尤其是一个比较大的链路压测时,压测人员基本无法对整个系统有较强的掌控能力,需要 1. 市场/运营人员 2. 模块开发负责人员 3. 运维人员 的参与,因此协调这些人员的工作就会十分重要。
压测的形态是怎样的?
- 压测可以分为基准测试和链路测试。基准测试是对单个模块的压测。链路压测是对一条业务流程的压测。
- 对于一个常规的压测流程,应当先对模块进行基准测试,在得到每个模块的性能指标后,再进行链路压测。
压测的结论有哪些?
- 回答压测的模型是怎样的,说明为什么选择这样的压测模型
- 回答在目标QPS下,当前的系统瓶颈是什么
- 给出压测过程中发现的不合理之处
压测的流程是怎样的?
- 分析业务形态,系统形态
- 根据业务需求,确定合适的压测模型
- 准备压测环境
- 准备压测数据、压测工具
- 确定系统可观测性,确定测试终止条件
- 压测执行,处理过程中的问题
- 根据压测过程,形成压测报告
- 根据压测报告进行分析,形成分析报告
压测的工程化实践
业务系统的压测(从链路来看),往往可以分为这两类:
- http 请求
- 其他类 TCP 请求
由于业务系统主要面向用户,因此对于 http 请求的压测是最多的,这也是市场上生态最好的类型。常规的例如 jmeter
、locust
、k6
、PTS
、loadrunner
,这是用于系统性压测的工具。另外,在开发人员保障的性能测试中,ab
、wrk
、go-stress-testing
这几个工具被经常使用,用于快速验证。
其他类的请求相对较少,例如 rpc
、websocket
这类。即使有一些实现,但真正结合到业务中时,会发现各种不满足需求。实际上,这类测试最好还是自己根据业务情况写项目实现。
压测项目是一个比较具有通用性的项目,因此可以考虑将其平台化,但目前来看,在最通用的 http 压测上,是比较容易平台化的,市场上也有很多,例如上面提到的 jmeter
、loadrunner
等。不过,市面上的这类工具基本都是用来进行 压力管理 的,而测试计划、测试脚本、测试报告 等方面的管理是比较弱的,因此,也有企业在开始做云端化的压测管理平台,比如 metersphere
,现在做得也基本可用了。
对于接口类的测试,通用性是非常强的,例如和 接口管理 结合,可以实现类似于:自动化生成测试用例
、流量录制
、测试跟踪(bug管理等)
、基于接口测试的性能测试
等等。实际上,这些功能 metersphere
也支持了,不过有部分是企业版的(如项目管理平台集成)。
对于接口类测试,我们当前使用的是自己开发的一个项目 super-apitest
,这个项目的最大亮点在于 基于json的模板化用例 ,这点可以认为和 jmeter 的 jmx 格式类比,不过基于 json 的格式,对开发者更加友好。
现在这个项目仅有一些简单的功能,例如适配了简单的触发界面、结果报告、结果通知,但想要真正做到平台化,还有非常长的路要走。
当前来看,这个项目可以在一定程度上进行平台化,主要的功能点有 3 个:
- 支持所有用例使用数据库管理 => 一切演进的前提
- 支持测试用例录制 => 极大简化用例生成方式
- 支持测试用例通过率统计 => 极大增强测试跟踪
如果做到这 3 点,这个接口测试平台已经基本可用了。
对于其他类型的功能测试,主要包括
- 工具库的单测和覆盖度测试
- 模块的功能测试
- 非 http 类的接口测试 (例如 rpc、ws、异步消息)
这些测试基本不具备很好的通用性,平台化的效率比较低,对于这类测试,平台的作用其实主要有:
- 测试触发
- 测试用例元信息管理
- 测试结果展示
基于此,可以认为,平台仅需要提供特定的接口,由各测试项目自行实现测试触发、测试结果反馈即可。
对于性能测试,如果全为 http 类接口,则平台化的效率较高,可以直接和 接口测试 模块相结合,由接口测试提供用例,由性能测试模块提供压测控制。
同样,对于非 http 类接口而言,性能测试的通用性就比较弱了,比如各个项目的性能。那么平台依然可以提供测试管理接口,由平台来做触发和结果采集,实际的测试执行由各业务项目自行处理。
功能测试和性能测试的关系
功能测试的目的在于保证功能的正确性,有时会有比较复杂的校验逻辑,测试用例集的组织形式经常为一个功能。
性能测试的目的在于摸清一些功能或场景的最大(合适)并发度,用于排查性能瓶颈和做线上资源容量规划,校验逻辑往往比较轻量,着重在压力 ,测试用例集的组织形式尝尝是一系列场景,并且十分关注各场景的比例,目的模拟真实用户的请求。
压测项目的价值有多大
根据压测的两大目标来看: 1. 发现系统瓶颈,提供优化建议 2. 回答线上容量问题
对于第 1 点,这是项目开发时需要的,例如开发一个通用的库,需要根据压测的结果进行优化。实际上,这是任何一个开发工程师都需要具备的能力,尤其是写中间件的工程师。
这种情况下,压测基本上是驱动这个项目进化的源动力之一。也是业务方评判这个项目的优劣及适用性的一个很重要的标准,业界流行的 redis
、kafka
、mongo
、mysql
等这类中间件,都是直接在发行版中自带 benchmark 工具。
对于第 2 个问题,大多数时候需要链路压测。最常见的系统压测是基于 http 这类 “request/response” 的,而这也是测试工程师最常接触的。目标在于找到整个链路的性能峰值。
毫无疑问,在项目开发过程中,我们需要回答第 1 个问题,而往往这个问题需要研发工程师自己回答。但从实际的情况来看,对于大多数业务场景,这类问题是比较基础的问题,如果项目中有比较高级一些的研发工程师在技术评审时下点功夫,基本就能将这些问题扼杀在摇篮里。
也就意味着,业务系统做这类压测,原因往往有两个: 1. 技术管理体系不成熟,代码质量得不到保障。 2. 跟其他业务有所关联,需要自证。
如果要回答第 2 个问题,就需要链路压测,这也是最被大家所熟悉的压测,这类压测往往需要一个团队来执行,主要包含: 1. 测试工程师
2. 运维工程师
3. 研发工程师
4. 业务人员(运营/产品)
。 在新项目上线、大促活动等情况下,一般需要做这类测试,用于保障线上不会被打垮。
业界做的比较好的容量是怎样的
根据一些公开资料,有了解到使用机器学习的方式,得出各条件下对于机器资源的需求量。机器学习的来源,一方面是通过多次(很多)压测得到,另一方面,是通过线上实际数据反馈进行修正。
这样一套容量的机器学习方案确实是一个不错的选择,尤其是对于业务较多的企业,还是有不错的收益,例如阿里的本地生活就有这么一套。
性能保障的职责
- 由测试人员
- 由运维人员(sre)
- 由开发人员
- 由架构师
对于常规的 http 请求的压测,可以由测试人员负责,凭借测试人员对业务场景的理解,可以构造出符合需求的测试脚本,再使用特定的压测工具,则可进行压测,压测的结果也比较清晰,可以直接交给相关项目的开发人员去进行接口优化。
针对特殊项目的压测,和普通意义上我们认为的测试工程师所做的工作不太一样,常规认为的测试工程师,大多凭借对业务场景的理解,加上对测试(功能/性能)工具的掌握,能做针对业务场景的测试/压测。这种项目的性能测试需要对这个项目本身比较熟悉,往往需要自行开发一些压测的工具来进行压测,从上述描述的测试工程师所擅长的技能来看,不能很好匹配。
对于链路压测,一般来说需要准备的内容比较复杂,包含 压测目标确定
、环境准备
、压测场景构建
、压测脚本
、压测过程控制
、项目配置/环境配置调整
、压测资源监控
、压测报告
、压测结果分析
等一系列环节。
这些环节过于复杂,对于任意一个工程师而言,都是几乎无法完成的。因此,往往需要一个团队来配合。团队内的分工大致如下:
- 业务人员(产品/运营),负责压测目标的确定(业务侧视角)。
- 测试人员,负责压测场景梳理、压测数据准备(协同研发人员)、压测执行、压测结果收集、压测报告
- 研发人员,负责standby问题排查、环境配置调整
- 运维人员,负责环境准备、协助排查资源问题
- 架构师/高级开发人员,负责压测结果报告分析、优化方案
文档直通车
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!