京东物流常态化压测实践
作者:京东物流 王江波
一、常态化压测建设目的
为什么做常态化压测?
目前面临主要问题,性能问题滞后发现,给大促带来不可控风险。目前日常需求频繁迭代,系统配置的变更、上下游依赖的变化、服务器资源置换等诸多因素均会对系统性能产生一定影响;日常很难做到对所有新项目或需求上线前后都进行压测,这就往往导致了很多性能问题推迟到大促压测期间才被发现。
大促备战压测备战时间紧、任务多,压测备战压力较大, 在 11.11 复盘中,有些部门工时统计中,压测占了较大一部分工作量。而且性能问题相较于其他问题,优化难度大、修复周期长,在大促备战多专项并行资源紧张情况下,频繁的系统调优给整个大促带来不可控的风险因素。
基于此,引入常态化压测的手段,通过每周或每月的定期压测行为,持续把控系统性能表现,保证服务稳定性;同时将需求上线引起的性能问题前置暴露,及时定位优化问题;减轻备战压力,提升压测效率。
二、常态化压测实施流程
2.1 常态化压测
常态化压测是按照一定周期或特定触发条件而进行的自动化压测行为,通过在单容器/集群的周期性压测,从而达到监控性能指标变动、及时发现服务性能衰减风险的目标。
2.2 实施策略
通过三步走的方式,由浅入深,逐步在平台技术部落地常态化压测:
第一步 单机试点: 由于初次使用常态化压测,通过隔离单机环境的方式,了解了常态化压测的压测思路、执行流程、压测平台能力支持及风险点摸排;
第二步 集群试点:在履约、基础平台选择星级核心服务, 在线上环境试点小集群(2-3 台)常态化压测任务执行,从线上业务影响、上下游依赖影响、压测平台能力支持、线上压测风险管控等多方面评估常态化压测在线上集群落地的可行性;
第三步 全面展开: 根据履约、基础平台的线上常态化压测集群实践,推广至全平台技术部,并结合 Kit 压测工具,建立核心服务性能数据看板,统计汇总压测结果性能报表,使服务性能趋势可视化展现;开通大促压测绿色通道,常态化压测达标的服务,大促压测绿通。
2.3 实施流程
常态化压测接口:优先选择覆盖业务主流程的核心接口,ops-review 的核心服务中星级认证的接口。
压测模版任务选择基准:
1)根据大促生产峰值流量模型结合服务器资源使用情况设置压测模版任务;
2)梳理链路依赖接口调用,按照最差下游依赖的承载上限并结合自身接口性能从调用量的角度设立压测模板;
3)对于没有下游依赖的服务,按照系统自身最佳处理能力,从吞吐量或 cpu 角度设立压测模版;
压测频率:链路长复杂接口,建议每天执行;自闭环的系统推荐按照上线频率执行。
压测窗口期: 和产研确认业务低峰期间,指定常态化压测任务的执行时间。
压测环境: 生产环境单机或者小集群进行常态化压测。
压测数据: 建议使用 R2 录制线上的真实流量作为常态化压测的入参,保证压测结果的有效性。
压测结果: 每次压测结果测试同学值班跟进,对不达标的接口,行云 bug 持续跟踪,协同研发进行性能分析、问题排查、压测任务维护。
压测工具:forcebot 常态化压测及 R2
三、常态化计划
•2023-Q1 在履约、基础进行常态化压测试点,形成最佳实践,并进行技术赋能分享。
•2023-Q2 季度推广至平台技术部-配运和交易条线,618 大促前平台技术部完成核心 0 级读服务 125 个基于 jdos3.0 的常态化压测建设。
四、基于流量录制的高保真压测
双十一大促刚过,在大促备战时很重要的一个环节是对各大核心服务系统进行压测,以保证系统在大促期间的稳定性,同时根据压测结果为大促扩容提供数据支持。那么如何进行高保真压测,使压测结果更接近于线上真实性能表现?在整个压测过程中,压测数据的准备是其中非常重要的环节,很大程度上决定了压测结果是否真实可靠;
随着业务的不断发展,不仅用户流量、业务场景越来越复杂,服务的调用关系和模块也越来越繁多,数据构造越来越困难,简单的数据集无法模拟线上真实的业务流量,流量配比不真实容易导致压测结果失真。
目前各大公司进行模块级压测或者全链路压测基本都是采用流量录制的方式,先对录制的流量进行存储,然后对流量进行编辑、过滤后通过压测引擎向被测服务发压;本章结合 Forcebot 压测平台,详细介绍如何使用 R2 平台录制线上流量进行高保真压测。
4.1 流量录制压测
利用 R2 平台录制线上流量进行压测的基本框架图如下所示:
1、用户访问线上服务,产生基于用户的真实流量;
2、测试人员在泰山平台 R2 工具管理端创建录制任务,任务启动时下发操作指令到 ducc,再通过 ducc 下发录制指令到线上服务端(线上服务已经开启 pfinder 并接入 R2 平台),开始录制线上流量;
3、录制的流量会上报至 R2 工具端,并且将采用数据进行存储;
4、流量录制完成后,可以在 Forcebot 压测工具平台创建压测脚本,Forcebot 平台已经和 R2 平台对接,请求 R2 服务端获取回放流量地址,进行录制流量装载;
5、Forcebot 平台获取到流量后,即可以正常通过压力机向被测服务发压,执行压测任务。
4.2 录制压测流量
根据系统架构及压测场景分析,选择需要录制流量的接口及场景。
•若压测时仅考虑单个接口,那么录制单个接口流量即可;
•而有的应用是多个核心接口,需要混合场景压测,在录制流量时需要同时对多个接口流量进行录制;
•当然,你也可以在录制任务中设置仅录制请求或响应符合某种特定业务场景的流量;
① 创建压测流量录制任务:选择入口应用,设置录制任务的名称及文件大小,注意:一般在进行压测流量录制时,建议录制所有场景流量,尽可能地高保真生产实际流量;在创建录制任务时,建议录制文件大小不高于 2G;
流量录制策略包含了手动录制、定时录制及周期性录制。在进行常态化压测时,为了避免流量过于老旧与当前生产流量偏差较大,可以在 R2 平台上创建一个周期录制流量的任务,按天或按周录制一遍生产流量,以保证压测数据的即时性。
② 选择要录制的起始服务,可以选择多个接口同时录制,平台会展示出接口调用链路,可以针对调用链路上的服务或中间件等同时开启录制,然后选择录制的实例,设置后任务之后就可以开始执行录制。
流量录制完成后,即可在 forcebot 压测平台创建压测脚本;
4.3 压测脚本创建
4.3.1 单接口压测脚本
在脚本管理中创建一个 JSF 回放脚本,编辑录制信息配置,选择要压测的应用、对应的 R2 录制流量任务,Forcebot 支持在京东私服平台上搜索或者手动上传 JSF 文件(jar 包),平台会自动然后解析 jar 包中的类和方法,调用 jsfOpenApi 获取接口别名和直连的 ipPort。通过以上方式获取接口服务相关信息,快速搭建 jsf 接口的环境。选择要压测的接口、jsf 别名以及压测的方法后自动会生成压测脚本;生成的脚本中默认关联了选择的 R2 录制任务中的录制请求,可以直接进行压力测试。
如下图所示,你可以进行内网环境校验,可以校验脚本是否能正常获取到流量并向对应接口发起了实际请求,这也是压测前的必要步骤,验证脚本通过之后进行保存,就自动生成了相应的脚本及 lib 文件;如果是单接口场景压测,到这里就可以使用该脚本去创建压测任务了。
值得注意的是,这种方式生成的脚本是不可编辑的,需要编辑脚本得自定义创建脚本;到这里,聪明的你一定想到了,这里页面仅能选择一个接口的其中一个方法,如果想要对同一个接口的不同方法或不同接口进行混合压测应该怎么办呢?不要着急,答案已经在路上了。。
4.3.2 多接口混合压测脚本
在实际生产中,我们的应用往往会提供多个接口,或者同一个接口上会提供不同的方法服务。我们在压测的时候如果仅仅按照单个接口来进行压测,这样的压测数据仅能反应单场景交易下系统本身的性能表现,而实际生产中,尤其是大促时,系统往往在同一时间需要处理多个接口请求,系统资源也是多个接口共享的,所以混合场景压测更能反映系统真实处理能力;
在进行混合压测前,需要首先明确各个接口场景在同一时间段内的调用量比例是多少,在创建压测脚本的时候,需要根据这个比例来设置每个压测场景下压力请求占比 rate;
步骤 1: 生成标准的 JSF 回放脚本
在自定义脚本之前,先按照 3.3.1 所述生成一个标准的 JSF 回放脚本,以及依赖的 lib 文件都会自动生成;
步骤 2: 生成自定义脚本
在步骤 1 中生成的默认脚本是不可编辑的,可以查看代码时生成自定义脚本,然后对自定义的脚本进行编辑。
① 首先定义接口路径及其方法,对应不同接口的别名,然后是根据不同的接口进行流量加载;
其中 ipList 是指定被压测的服务器 ip 及端口,如果接口别名下是集群部署,只想要对其中某一台机器进行压测的话,需要指定 ip 及端口;
② 针对不同的接口创建回放事务,此处接口路径、接口的加载流量、接口别名等都需要一一对应。rate 为该脚本中涉及的多个接口的调用量比例,比如接口 1:接口 2:接口 3=7:8:5(可参考大促或日常调用峰值期间各接口的调用量比例),则需要在 testCase 中设置相应的压力比。
③ 因为多接口涉及接口路径、流量源以及接口别名各不相同,需要将默认的无参 doReplay 方法,修改为传参方法
④ 脚本修改完成后点击保存
⑤ 相同接口不同方法的混合压测脚本创建同理,区别在于同一个接口,别名是一致的,不需要额外再指定其他接口别名;
步骤 3: 导入附件 jtm.properties
在步骤 2 中自定义脚本编辑完成后,进行校验执行时还无法成功,因为脚本还缺少流量录制回放的附件文档。保存脚本后,返回上一级目录,将步骤 1 中生成的标准 groovy 脚本中的附件 jtm.properties 下载到本地,然后再将该附件文档上传到我们自定义的脚本中,并修改脚本的附件文档。在附件文档末尾添加
jtm.replay.recent.record.num=1,指定每次压测时都获取绑定周期性流量录制任务最新录制的流量;
4.4 双十一大促高保真压测实践
有了 R2 流量录制平台提供的便捷,让获取线上流量不再成为难事,可以帮助我们快速的完成压测数据的准备,同时压测流量高保真还原实际业务场景。
在本次双 11 大促,物流 promise 业务线全面采用 R2 流量录制的方式进行大促压测,自压测结果更加接近线上接口性能,真实性达到 90%以上;为大促资源扩容评估提供了更加精准的数据支撑。同时,通过这次高保真压测,我们发现多个系统性能问题,其中包含极限业务场景下的可用率降低的问题。
下图为采用 R2 流量录制压测、军演压测与双十一大促开门红的性能对比。
五、USF 常态化压测实践
基于 focebot 的常态化压测能力,选择 USF 选择 3 星核心服务进行常态化压测实践,选择 TOP4 核心接口,使用 R2 的录制线上流量,根据大促的流量模型进行的混合场景常态化压测,持续监控 USF 的核心接口的性能情况。
forcbot 常态化压测工具支持,压测任务复用(支持流量录制压测任务)、可配置性能基线包括响应时间 TP99 和 TPS 的和服务器 CPU 等资源指标设进行性能基线设置,并根据性能基线判断压测是否达标,以及可以设置不达标的压测结果自动创建行云缺陷,进行性能问题跟踪处理。并且还提供压测监控对比数据以及压测结果历史记录,便于对性能结果和问题进行分析,自动发送压测邮件通知,及时同步性能压测结果。
目前 forcebot 的常态化压测支持以下功能:
•1、支持压测任务的复用,可使用历史的压测任务,不用单独创建压测任务和脚本,支持 jsf、http、自定义的 jimdb、jmq 以及回放脚本。
•2、可配置定时执行任务,灵活执行时间。
•3、可支持流量录制。
•4、可自动创建行云缺陷
•5、可配置压测的是否达标基线(生效:是否将指标用于压测达标率统计;勾选会作为指标之一,不勾选则在达标率计算时不作为统计指标。 达标:勾线生效的指标值同时满足时,压测结果即为达标;反之,有任何一个指标值不满足条件,压测不达标。
以下为基于 USF 进行的常态化压测。
5.1 压测物料准备
压测数据:
•选择业务高峰期 14:00-16:00 录制线上 10%对应 6 台机器流量,录制【公共集群】入参 1G。(后续会考虑多个集群)
•录制接口服务是 USF3.0 线上 TOP4 的接口,已完成星标治理,达到三星的接口,完成可用率、TP99、以及有降级和限流方案治理。
压测场景: 混合场景设计(模型)
应用部署拓扑图:
压测环境:
压测环境目前是与线上同配置的单实例的 UAT 环境。
•与线上的现数据库、缓存保持一致,均已同步线上数据。
•压测环境数据库的配置和缓存服务的配置与线上保持一致。
1.线上机器配置 * 实例数 60
2.应用服务器配置:4C8G
3.数据库配置:16C64G 内存
4.压测机器配置
5.应用服务器配置:4C8G
6.数据库配置:16C64G 内存
5.2 压测风险评估
•压测环境选择:
•1)先在同配置的 UAT 环境常态化压测,根据性能结果不断调整性能基线
•2)稳定后再复用生产环境的应用和中间件进行常态化压测。
•任务执行窗口:
•选择业务低峰期进行压测,结合 ump 监控 USF 服务的高峰期一般在白天的上午 6-9、9-11、14-17 系统使用的高峰期。所以目前任务执行的窗口期是工作日 17:40。目前是有人值守的报警信息及时处理,监控应用和数据库相关情况。
•压测链路同步:
•压测上下游链路梳理,确定压测范围、压测量级、压测时间,同步相关方达成共识。
5.3 常态化压测任务创建
5.3.1 压测模版任务选择准则
•复用历史的压测任务(模版任务),直接创建常态化压测任务。实际选用历史的压测任务场景时,建议根据系统的实际情况来选择,一般可以选择性能拐点场景或者压到预期值的场景(如 CPU60%或者 TPS 达标),一般建议不要压测系统资源饱和的状态场景。
•示例:此处 USF 我们选用历史的压测任务,是接口满足双十一的吞吐 TPS 的场景,此时服务器的 CPU 压力在 27%,数据库的 CPU 在 36%。
模版任务选择:
查看任务,可以看到该场景下的执行的脚本,发压相关设置并发线程数、执行的模式(并发模式和 RPS 模式)、执行时间,可根据需要进行一定的调整。
5.3.2 压测定时任务设置
•可以通过周期或者 Cron 表达式指定执行周期,usf 此处使用 Cron :0 40 17 * * ? 每天下午 5 点 40 执行。并在此处设置目标线程数和执行时长。(这个会覆盖压测任务中的线程数和执行时长)。
•常态化压测执行的频率以及执行的时间参考根据代码上线周期和业务的调用低峰时间段综合定制。
1)执行模式-RPS 模式
绑定的是压测任务是 RPS,那么我们创建的常态化压测任务也是 RPS 模式。目标 QPS 设置,并非脚本中所有接口的 QPS 的和,而是脚本中占比最大的接口对应的压测目标值,如果配置错误会导致过度发压。
2) 执行模式-并发数模式
绑定的压测任务是并发模式,那么我们创建的常态化压测任务是并发执行模式。目标线程数设置。
5.3.3 压测基线设置
•根据压测任务对应的压测场景,根据事务名称(接口方法)设置合理的压测基线,如果关联的压测任务是混合脚本,那么可以分步骤设置多个接口事务(事务名称默认:forcebot.测试方法名 )的性能基线。 一般关注的指标平均 TPS、TP99、错误数、CPU 监控。允许波动的范围,根据接口的实际情况给一定的波动空间。若大于设置的波动范围,并且选中设置提交行云缺陷,就会自动提交行云 bug,便于 bug 跟踪闭环。
•基线指标设置注意点:如果基线值特别低的情况,那允许的波动范围百分比需要设置的比较大才可以,否则很小的波动都会被认为压测不通过。基线波动范围,具体接口具体分析,研发和测试达成共识,
1) 自定义性能基线设置
•USF 的 findUserInfo 服务设置示例:
•TPS 基准值=2700,允许波动范围 10%。(2430-2970) 上下浮动
•TP99 基础值=12ms,允许波动范围 50%。(12ms-18ms) 上浮动,时间相关的是向上浮动。
•错误数基准值=0,允许波动范围 0。
•CPU 监控基线值=25%,允许波动范围=20%。(20%~30%)上下 浮动
事务名称: 目前无法自动识别,可以写脚本的中事务名称默认是 forcebot.测试方法名,也可以增强脚本使用自定义事务名称就是
TestUtils.transactionBegin("findUserInfo"),即 findUserInfo
性能基线设置例如:接口性能 tp99 在 12ms 左右,此时基线值设置为 12ms,允许波动的范围如果设置为 10%,那允许的波动范围就是 12ms*10% = 13.2ms,超过 13.2ms 就认为压测不通过,这显然是不合理的,此时需要根据我们的接口 tp99 最大接受范围来设置允许波动百分比。
2) 多接口性能基线设置
自定义基线设置中,可以添加多个接口事务,该事务就是脚本中的事务名称。
默认事务名称:forcebot.测试方法名
自定义事务名称: 如 TestUtils.transactionBegin("findUserInfoByOrgCode");
5.3.4 行云缺陷跟踪
对于不满足性能基线设置各项指标值,常态化压测结果就为不达标,若该任务配置开启了自动创建行云缺陷,就会对不达标的执行结果自动提交行云缺陷,这样可以保证 bug 生命周期各阶段可追溯,保证问题及时处理解决。
5.3.5 监控定位问题
可以查看一段时间该服务的性能趋势,如果接口性能波动较大,需要进一步排查接口性能下降的原因。
1) 监控数据-TPS
2) 监控数据-TP99
3) 执行记录对比详情 PK
执行记录中,有脚本版本和,是否达标以及 bug 详情。选中达标和不达标的结果,进行 PK 对比,对比项中有 TPS、TP99、Error Per Second 等指标。
USF 相关接口的压测结果,达标和不达标的 PK 如下:发现是 12-04 存在一次错误调用,进一步跟踪错误产生原因
5.3.6 邮件发送压测结果
设置接收人邮箱,将邮件抄送给研发和测试相关人,压测结果邮件中会提供压测数据汇总显示,如果压测结果中某一项指标不达标时(超出设定值及波动范围)时,则此次任务视为不达标。结合监控信息以及执行时间段的日志与研发共同定位问题或者是性能基线指标的调整。
邮件如下:
版权声明: 本文为 InfoQ 作者【京东科技开发者】的原创文章。
原文链接:【http://xie.infoq.cn/article/2a3e9e05c321f2721415e2fe2】。文章转载请联系作者。
评论