原创:俩右(微信公众号ID:CodeGeek_Lee),欢迎分享,非公众号转载请保留此声明。
背景
最近大半年团队内部搞了个新项目,这个项目主要是用于对用户流量的决策,大致上可以理解为 AB 测试的原理,我们在 AB 测试的基础上进行扩展。支持策略配置、规则配置、特征获取、策略静态资源配置、特征动态化、决策树等。流量决策系统承担业务的流量决策,结合各种策略规则的配置提高业务转化率。
由于一直以来专注于需求开发,而忽略了稳定性方面的事情,所谓稳定性建设,规范先行。制定一些有效的规范,可以让开发避免很多坑。而压测是稳定性中比较重要的环节,通过它可以了解系统的一个运行能力。
粗略版系统架构图:
压测是什么 为什么要做
压测是什么
压测一般指性能压力测试,通过压测可以了解系统稳定性和性能,通过压测结果进行系统的调优。
做压测有什么用
就比如我现在做的这个流量决策系统,一直以来忙于需求开发,看似在线上运行的好好的,可心里总是没有底。因为不了解系统的一个能力,不知道它能够承受多大的并发量,并且这些都无从考证。
通过压测摸底我们可以清晰的了解系统的每一个运行指标,例如机器负载、QPS/TPS、响应时间等,这样就大概知道系统的一个运行能力,做到心中有数。后续可以根据压测结果进行系统调优。
压测中的角色
就我本次的压测过程来看,都有以下几种角色参与其中:
-
研发
研发作为系统摸底压测的发起者参与其中,协调各方资源和时间。负责评估系统能力制定压测方案。
-
测试
测试作为系统摸底压测的执行者参与其中,负责准备压测环境、压测场景、压测脚本等工作。
-
leader
leader 作为系统摸底压测的把控者参与其中,负责对压测方案的可行性进行评估、压测方案的评审。
-
产品
产品作为系统摸底压测的业务逻辑校验者参与其中,在线上进行压测的时候,避免不了要造测试数据,就比如我们这个系统需要线上创建一个策略,产品负责检测配置的策略是否符合实际的业务逻辑。
-
系统下游
系统的下游作为系统摸底压测的辅助监控者参与其中,在进行全链路压测的时候避免不了要调用下游系统做一个全链路的系统压测,所以需要通知系统下游,让他们做好压测的准备,时刻观察他们的系统情况。
线下压测
线下压测指的就是非生产的压测,就比如我们平常本地的接口压测,或者为了保证线上的稳定性而选择压测预发环境等,这些都是线下压测。可以通过 JMeter、Apache ab 等工具来进行。
线下压测的环境(比如 服务器配置、网络、节点数量等)和线上完全不一样,仿真度不高。并且很难进行全链路压测,压测的数据也只能作为参考,并不真实可靠。
线上压测
线上压测指定就是生产环境的压测,我们可以分为很多方式来压测,比如读压测、写压测、混合压测,也可以使用隔离集群或者单机压测,主要就是将线上部分机器摘除,线上流量无法进入然后将压测流量打到摘除的机器上,这样的压测方式比较安全。
线上压测应该进行全链路压测,因为可能存在一个非核心调用导致整个系统出现问题,所以为了保证压测的真实性应该通过全链路压测来发现问题。
压测前的准备
监控报警、系统运行大盘
压测不能盲压,通过肉眼是无法实时感知系统的运行情况的,所以监控报警、系统运行大盘一定要配置好。监控报警可以帮助我们实时监控系统的一些指标异常,系统运行大盘可以帮我们了解系统压测时的一个运行能力。
所以在压测开始之前,一定要检查系统中的基础监控是否完善,如果有缺失要及时补充上。如果没有系统运行大盘(系统运行状态的图表)要在压测前配置出一个来,方便实时查看系统运行能力和记录压测数据。
周知相关人员
在前面的介绍中我提到了几个在压测过程当中的角色,除此之外还要通知系统的上游。最好把大家拉到一个群里,这样方便沟通和交流。我们不能悄悄的就自己进行压测,然后谁也不知道,到时候出现了问题,大家都是一脸懵。我们要协调各方资源做好充足的准备。
通知系统的上下游是为了让他们做好准备。
如果上游不知道你进行压测,当你进行压测的时候他们调用你的接口超时了、报错了。紧接着你就会受到一堆消息轰炸,咋回事啊?系统咋超时?赶快看看
影响调用方对你系统的信任度,系统这么不稳定,后续还有人敢用吗?
如果下游没有通知到,并不知道你压测,就拿我这次的压测来说,我们主要的压测都是读请求,一个获取策略结果的接口,内部可能会查询多个不同的特征值,会多次和特征系统进行交互,那么当你以100 qps 进行压测的时候,到下游特征系统那里可能就是1000 qps,为什么会这样呢?因为这就是平常所说的 ”读放大“。 你的系统里面的一个请求可能会多次请求下游方,这里大家一定要多注意,最好在压测前能够评估出一个接口放大了多少次请求给到下游。这样下游做好准备和预估是否可能,不要压测自己系统把别人的系统搞出故障了,那就得不偿失了。
制定压测目标
做任何事情之前我们都要先确定目标,对于压测也一样。我们需要确定一个目标然后朝着目标前进。尽量让测试的目标有一个量化的标准,比如 最大 QPS 压到多少、响应时间不应该超过多少等等,让压测目标有一个量化的标准。这个需要自己系统做一个评估,在根据下游方的系统状况来确定。
准备压测场景、方案
场景
由测试同学准备下场景,这个场景指定就是要压测接口的数据。就比如压测一个接口,这个接口不同的入参,内部会有不同的调用逻辑,这里我们要通过入参列出几个场景。尽量覆盖到接口内部的分支逻辑。
方案
确定测试类型:
-
基准测试
基准测试是指单线程对单个接口进行测试,主要用于调试测试脚本的正确性。
-
容量测试
容量测试是检查系统处理的最大业务量,在测试过程中采用梯度加压的方式不多增加请求数量,通过观察系统运行状态变化,找到最大的处理业务量。本次流量决策系统的压测就是采用的这个测试类型
-
负载测试
负载测试用于测试单个接口在不产生任何错误的情况下能提供的最佳系统性能。这个测试可以mock掉下游,专门测试系统能力。
-
混合业务测试
这个就像是集成测试,通过模拟线上的接口调用比例进行编排,采用一定的加压方式进行测试。有点像模拟用户调用流程的测试。
确定加压方式:
-
瞬间加压
瞬间加压是一次性将所有流量打到系统上,主要考察系统应对突发流量、瞬时流量的应对能力。
-
逐渐加压
逐渐加压是模拟系统一天的运行情况,从早到晚,从业务高峰到业务低峰。测试系统在一定时间内的抛物线趋势。
-
梯度加压
梯度加压和逐渐加压类似,本质的区别是逐渐加压是一点一点的达到最大值,梯度加压是一个梯度一个梯度的加压,一个梯度完事会上升到另外一个梯度,会省略掉中间的一些压力值。
准备压测环境
准备压测环境时可能需要搭建和配置系统。编写和调试测试脚本。我本次使用的公司内部的压测平台,所以不需要搭建压测的环境,只需要准备测试的脚本。
大家在压测之前一定要验证脚本的是否可用,还有需要注意线上配置的压测数据是否正确,我本次就碰到了,测试脚本没问题,但是线上的压测数据配置的不对,导致在压测过程出现很多问题,不是预期的结果,耽误压测的进度。
压测的执行
压测的执行指根据我们制定的压测方案,执行各个压测场景和压测任务,并通过观察和监控系统资源、数据库、缓存、消息队列的运行情况,判断系统是否满足压测目标。通过测试过程中的数据做记录和分析,形成压测报告。
总结有以下几点在:
- 观察系统状态
- 记录压测数据
- 总结压测报告
制定应急预案
在系统压测之后,我们会发现一些系统的瓶颈,在系统优化之后会有一些提升。但还是避免不了一些潜在的风险,例如网络抖动、机器掉电等。为了防止这类问题的发生,需要针对一些情况制定出应急预案。
应急预案的制定可以将系统按照层级划分,每个层级对应到负责人,制定一些应急办法。就比如接入层,如果发生故障,应该怎么办 ,是切流、熔断、还是降级,或者业务隔离的处理。
压测工具
公司自研
我们这次压测使用的就是公司内部的压测工具 Ultron 压测平台,支持接口级压测、全链路压测、仿真度量化、容量预估等。如果公司内部没有压测工具可以参考一下工具来操作。
jmeter
jmeter 是 Apache 开发的基于 Java 的性能压力测试工具,用于对 Java 开发的软件做压力测试,它用于测试静态、动态资源、http服务器等。
jmeter 可以用于对服务器、网络或者对象模拟巨大的负载,在不同类别的压力下测试其强度并分析整体性能。
ab
ab 是一款针对 HTTP 实现的服务进行性能压测的工具,它最初被设计用于测试 Apache 服务器的性能指标,特别是测试 Apache 服务器每秒能够处理多少请求以及响应时间等,但此命令也可以用来测试一切通用的 HTTP 服务器的性能。
欢迎大家一起来交流
Email: 644968328@qq.com
WeChat: lx6688s
GitHub: github.com/li-xiao-shu…