导读
作为58自研的一站式性能测试平台,麒麟旨在帮助业务线便捷地完成性能测试,精准评估服务性能和容量等,从而提升服务的稳定性和可靠性。平台包括管理中台、数据监控、报告计算、任务调度和压测引擎等模块,只需用户提交服务、压力参数等信息,即可快速、简单地进行性能测试,平台可根据任务信息动态调整压测资源,无需用户花费大量时间和精力去搭建和管理复杂的压测环境,让其更多地将注意力集中在性能分析、系统调优上。
背景
随着业务发展,公司对接口压测的需求越来越多,尤其是春运核心接口性能评估、冲量活动、秒杀活动等众多场景,都需要压测来保障业务稳定。传统压测,只能借助JMeter等工具,而使用工具压测,一方面需要学习成本较大;另外也存在很多弊端,如压测接口、文档等无法统一记录管理,多人并行测试,结果报告、性能数据,无法实时共享;对于历史数据,本地删除后,无处可查;另外,如果要对SCF(58自研RPC微服务)压测,需要额外开发压测扩展,成本大;并且手动压测,需要频繁申请压测资源,资源利用率低。基于上述种种原因,我们提出建设麒麟平台的想法。
平台发展阶段
自2020年立项启动以来,麒麟平台每月一版本迭代,不断地进行优化、扩展。发展阶段可以分为以下几个:
3.1 初期支持阶段
麒麟平台在初始阶段,根据用户需求,优先支持了对SCF服务的压测,并提供了实时数据监控和历史执行结果报告查看等功能,之后陆续支持了HTTP&JMX压测、参数化以及断言,以满足更多的使用场景。同时也在不断收集用户反馈,调整、优化功能,目标是建设高效、易用、稳定的压测平台。到2020年底,平台支撑了春运核心大流量及冲量活动压测。
3.2 扩展阶段
在推广过程中,大部分用户反馈的问题均为执行失败问题,主要是因为服务信息填写错误导致的,故为了降低用户问题排查成本,方便快速定位问题,避免误压,平台新增任务调试功能,并丰富了任务执行日志,同时调整相关页面交互,优化用户体验。平台在V1.0版本完成了双引擎(Gatling和JMeter)系统融合,并正式在集群各事业群推广落地使用,之后支持了超职季、挑房节等大型活动压测,与春运容量评估系统整合,支撑春运期间各事业群的压测与容量评估工作。
3.3 提升阶段
平台的快速发展也面临一些挑战,其瓶颈和不足也凸显出来。由于底层采用了master-slave模型,存在master瓶颈问题,很难满足像k8s性能压测、赶集投放接口等QPS 30W以上流量压测,为了解决这一问题,平台在V2.4版本中进行了架构调整,通过调度中心,动态拆分任务,实现压测资源的动态伸缩。同时,对底层压测引擎也进行了一系列优化调整,压测能力提升了近50%。针对结果报告实时性差的问题,对报告模块也进行了升级,通过Kafka-Flink DataStreaming实时计算,延迟降到ms级别。
平台功能
麒麟主要包括管理中台、压测引擎、调度系统、数据监控、报告聚合五大部分。
4.1 管理中台
管理中台包括任务管理、执行历史管理、用例管理、资源文件管理、权限管理、平台数据维护等模块。用户通过中台界面进行任务维护、执行、数据查看。对于任务新增,除了支持页面新增任务,还提供了任务复制、第三方接口管理平台接口导入、CURL导入等功能,来减少用户使用成本。另外,平台引入用例管理模块,维护接口信息,实现任务信息高效复用。对任务执行,提供任务调试功能,方便用户定位问题。在风险控制上,通过权限控制、内外网压测流程约束、一键停止等手段,来保障压测的安全性。
通过平台化管理压测数据,用户无需了解底层引擎实现、开发扩展,只需填写服务信息,进行一键压测,压测准备时间成本由天级别降低到秒级,极大提高了用户的压测效率。
4.2 压测引擎
支持多协议
平台不仅支持HTTP,还支持SCF(RPC)、WMB(58自主研发的分布式发布/订阅产品)压测,并支持上传JMX、SCALA脚本压测,来满足更多场景化的压测。平台会根据系统规则,自动调整压测脚本内容,如修改参数化文件路径、添加预处理、监听器等元件,无需用户额外处理,简单方便。多压力模型
压测模型除了支持梯度、按时间、按照循环次数压测,还支持自定义组合模型。入参多样性
支持参数化、随机变量、自定义函数丰富的断言
支持对服务的code、body、header等内容断言,此外支持多种组合断言
4.3 调度系统
任务执行,系统根据任务信息,自动创建压测容器,动态调整资源,并可对任务资源进行自动回收,实时维护任务状态,无需用户了解压测引擎实现、分布式执行、机器资源使用等情况。
4.4 数据监控
平台提供了丰富数据看板,可实时查看服务、发压机、被压机等各项性能指标,包括QPS、响应时间、错误率、CPU、内存、网卡,以及SCF访问量、SCF访问耗时、SCF错误率等数据。除了数据监控,平台还提供多维度的执行日志,如任务初始化、依赖下载、执行进度、请求数据处理、调试结果、结果响应、断言结果等,方便用户分析定位问题。
4.5 结果聚合
平台可自动生成详尽的性能测试报告,包含各项性能指标、聚合报告,并支持报告下载、历史报告查看等功能。其中压测报告相关数据的计算,通过自定义Kafka-Backend-Listener采集任务数据,基于Kafka-Flink的DataStreaming实时计算,准确度高、扩展性好,延迟可达到毫秒级。
核心设计
5.1 SCF压测支持
SCF是58自研的RPC服务,平台若需支持SCF压测,需要做定制化的开发。以下是SCF的调用模式
5.2 引擎支持
对于底层压测引擎,JMeter不直接支持SCF压测,目前是通过自定义Sampler扩展,完成对SCF压测。压测引擎包括Sampler、SampleGui两大模块,Sampler用于压测数据处理,SampleGui用于提供交互界面,Sampler包括初始化、Sample处理、结束处理模块。
初始化处理
在请求服务前,需要一系列初始化工作,如获取任务信息、下载依赖、构建SCF client等,而初始化时间,受jar包依赖第三方包多少、网络情况、服务复杂度影响,耗时不可控。平台初期,初始化工作和Sample请求耦合在一起,因此任务的数据统计、结果报告准确度误差较大。V2.4版本将初始化工作前置到Sample请求之前,Sample只需要完成入参构建、服务请求、结果处理等工作,优化后,结果报告更精准。Sample处理
首先是获取用户填写的SCF入参内容,读取参数化文件,整合SCF入参,之后根据SCF入参类型以及入来构造入参Object,再使用初始化的client、method,通过invoke方式请求服务。结束处理模块
初始化数据的回收清除。
5.3 SCF信息维护
对SCF压测,需要的信息较多,如服务名、接口类、实现类、方法名、SCF版本、序列化版本、IP和端口、SCF密钥、入参等。由于需要录入的信息较多,在平台推广过程初期遇到最多的问题是用户填写的服务信息不准确。故为了简化用户SCF服务任务创建、降低用户填写错误率,平台在交互上做了一系列的优化,如自动限定对应的接口类、实现类、方法列表,并支持下拉联想,选择完方法后,自动填充SCF版本、序列化版本、入参等,并带出各环境IP list,若用户选择使用SCF密钥压测,系统自动校验密钥。而要完成上述功能,都依赖SCF服务信息维护。
具体实现方式如下:
SCF服务新增、更新后,麒麟接收制品库对应消息。
根据消息内容,获取服务坐标,自动下载服务依赖。
加载服务jar信息,解析服务名、接口类、方法、入参、服务分支等信息,同时调用服务管理中台服务,对解析信息进行二次校验、筛选,并对服务的基础信息进行补全。
为了避免消息丢失或者延迟,目前也支持手动新增SCF服务,只需填写服务名称、坐标信息,平台会自动对服务进行解析、对标等处理。
5.4 任务调度
在平台初期,压测的QPS需求较小的情况下,平台通过JMeter的master-slave模式实现分布式,此模式最大的弊端是master会成为整个系统的瓶颈,同时,发压机要一直处于在线待命的状态,非压测期间,机器零流量,造成了极大的资源浪费。大规模压测场景下,如赶集投放接口压测,目标QPS 70w,发压机有限,较难满足其需求,只能手动增加发压机配合压测。出于成本、性能扩展等考量,系统进行了架构升级,将master-slave的分布式模式,调整为调度系统分布式模式,平台根据任务的数据,自动计算使用资源,动态部署压测容器,压测结束后,压测容器自动回收,压测期间,任一容器初始化异常,停止任务。
任务调度包括两部分,调度中心Dispatch、压测平台Agent。
调度中心Dispatch
接收管理中台下发任务,进行任务拆分,并自动创建容器,分发任务Task到每个压测Agent,压测过程中,支持任务延迟、停止等操作。具体实现如下:
1)管理中台将任务下发给Dispatch。
2)创建任务Job(一个Job对应一个任务的执行id)。
3)根据Job信息,根据线程&QPS综合计算使用资源数,进行自动拆包为多个Task(每个Task对应一个压测Agent)。
4)根据拆包信息,批量创建压测Agent,并分发Task给Agent。
5)待Job的所有Task Agent创建成功后,下发任务执行指令给Agent。
6)所有Agent执行结束后,更新任务执行状态为完成态。若任一节点创建失败,则任务初始化失败。
7)在每个环节,都会更新Job状态,Job若对应多个Task,则Job状态更新为所有Task最小状态,任一环节异常,Job执行异常,终止后续动作。
8)待Job执行完毕或者执行异常时,回收压测节点、释放资源,结束压测。
9)调度平台实时接收管理中台下发的任务停止、延迟命令,将动作下发给Task停止任务、延迟任务。压测平台Agent
负责接收Dispatch下发的Task任务,进行任务的预处理,之后执行任务,并实时同步压测状态给调度中心,监听Dispatch下发的指令,如停止任务等,对压测进行相应调整。具体实现如下:
1)压测容器初始化后,拉取Task信息。
2)根据Task信息对任务进行预处理,包括参数化文件、依赖文件下载、JMX初始化等。
3)每个环节都会同步Task状态至调度中心。
4)初始化完成,监听调度中心的执行动作,待可执行后,执行Task,开始压测。
5)Task初始化、执行中,监听调度中心的停止命令,接收到停止命令,则立即停止压测,并同步状态至调度中心。
5.5 数据监控
5.5.1 数据采集
对于机器端相关监控数据,复用58中台能力,调用其OpenApi,实时采集机器的CPU、内存、网卡流量,以及SCF服务相关的数据,如访问量、访问耗时等,并通过采集压测数据,对服务请求数据进行聚合计算,提供压测的QPS、响应时间等数据。
5.5.2 日志可视化
随着压测的时间、QPS提升,压测过程中的实时日志数据量非常大,往往是G级别的,尤其是SCF压测,很难通过直接读取数据获取到实时日志。目前对发压机日志,通过Filebeat实时采集,同步到Kafka,之后消费Kafka数据持久化到ClickHouse,再提供可视化界面,支持按照机器、任务、不同时段等条件灵活查询日志信息。
5.5.3 日志记录
SCF信息复杂,信息填写错误率高,另外,执行结果受服务注册结果、服务可用性、依赖下载、版本更新等众多原因影响,而验证服务可用,并不能像http,可直接请求服务进行验证,极大地增加了压测执行测试失败的概率。故在Sampler实现时,提供了多维度的日志信息,以便用户直观、快速定位分析问题,包括初始化明细、依赖下载进度情况、执行结果、调试结果、入参预处理、响应结果内容、断言情况等。另外,作为压力机,日志丰富度的提高,必然会增大磁盘写入压力,影响机器性能,故在日志写入方面,也做了相应调优,可针对日志级别,根据任务配置,动态调整日志的内容。
5.6 压测报告计算
平台提供了丰富的压测报告数据,包括QPS、平均响应时间、错误率、请求量、最大响应时间、最小响应时间、响应时间90、95、99线等。虽然JMeter自带生产聚合报告的能力,但是压测时间或QPS较高的情况下,延迟极高,如,QPS为w级别、约十五分钟的压测,报告延迟可达十几分钟,并且平台接入调度系统后,每个Agent相当于一个独立的引擎,无法自动聚合多台机器的压测数据,另外,直接利用JMeter原生的计算方法,报告数据指标的扩展,是比较困难的。因此,对麒麟的压测报告计算模式做了调整,引入自定义DataStreaming,压测数据采集到Kafka,通过Flink计算,提升报告的实时性与正确性,同时解决分布式调度场景下聚合报告缺失问题,通过此自定义计算方式,可灵活扩展更多定制化的数据指标。目前已完成请求总数、qps、错误率、最大最小平均响应时间、响应时间50-999线等27个维度的数据计算。
其中在计算任务中位线、95线等数据时,因为要记录所有Sample的响应时间,而高QPS任务,Sample数可达千万甚至亿级别,若计算时存储当前执行任务所有Sample的响应时间,所需内存为G级别,对Flink机器内存消耗极大,严重影响计算的时效性,故在此部分数据计算时,调整存储方式,用TreeMap存储,响应时间作为key(ms为单位),响应时间对应的Sample个数为value,利用TreeMap有序排序的特点,高效遍历取出对应的目标值,极大减少了内存的使用,如,即使在Sample响应时间波动很大时,其对应的响应时间段也是有限的,往往在1ms-10s内,那么存储所需的key也不过是w级别的,所需内存为M级别。调整为此存储方式后,常规的QPS w级别的压测,报告延迟可缩小到ms。
5.7 优化效果
经测试,在服务、压测入参相同的情况下,压测半小时,目标QPS(18000),整体架构优化前后效果如下(备注:不同服务,因响应时间、性能等数据不同,以下数据会存在差异)
实践效果
麒麟在V1.0版本发布之后陆续支持了超职季、挑房节、春运容量评估等大型压测工作,目前已在11个事业部落地。支持10000QPS以上压测任务近200个,压测接口2300+个,压测次数达1.6w次,其中,自研SCF压测引擎,任务约占65%。
后续规划
目前,麒麟平台功能基本满足大部分用户的需求,已基本达到了我们最初高效、易用、稳定的目标,但是仍存在一些不足,如对全链路压测、数据隔离、更健全的熔断安全机制等。随着业务的发展,服务调用链越来越复杂,很难根据单一接口去评估整个系统容量,需要整个业务链进行全链路压测,而目前平台只支持单接口压测。同时,压测会产生大量的业务数据,必须要考虑不能对生产数据产生脏数据,目前针对写服务压测,使用测试账号,或者新业务压测完之后数据清理,存在一定风险和弊端,后续考虑通过压测数据隔离的方式,防止数据污染。另外,生产环境压测风险极高,目前虽然平台具有一些风险机制,如权限控制、一键停止、实时监控等,但是比较依赖用户的操作,时效性差。针对上述内容,后续规划如下:
全链路压测
支持场景化多接口模式,结合流量回放、SkyWalking等手段,以支持业务全链路压测。数据隔离
添加压测标识,压测数据落影子库,压测数据与真实业务数据隔离。熔断安全机制
压测过程中自动监控服务性能情况,动态调整压测QPS,当达到阈值时,自动触发熔断,停止任务,以此保障更安全的压测。
作者简介
赵茹:58同城 高级测试工程师
唐梦倩:58同城 高级测试工程师
本文分享自微信公众号 - 58技术(architects_58)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。