【积微成著】性能测试调优实战与探索(存储模型优化+调用链路分析)| 京东物流技术团队

一、前言

性能测试之于软件系统,是保障其业务承载能力及稳定性的关键措施。以软件系统的能力建设为主线,系统能力设计工作与性能测试工作,既有先后之顺序,亦有相互之影响。以上,在性能测试的场景决策,架构分析、流量分析、压测实施和剖解调优等主要环节中,引发对于系统能力底盘夯实和测试策略改进的诸多思考。

在性能测试阶段,剖析系统能力实现及调优方案,探索更优解及性能测试策略的提升空间。

二、热点数据存储模型压测实战及思考

通过性能测试,推测SKU库存预占场景,在不同存储模式下的性能瓶颈及风险。

数据架构升级后,SKU库存预占效率(TPS)提升2300%↑。

测试驱动,结合系统实现,论证缓存预热的必要性,并借助大数据分析,探索科学的缓存预热及保温策略。

结合新业务模式,思考更加科学的测试数据构建思路和测试过程提效方案。

1、压测场景

库存预占,是指在订单接单环节,为单据提供SKU库存短暂预留。物流仓配订单接单环节,会发起SKU维度的库存预占行为。

库存中心通过“库存预占主应用”中的预占接口,对外提供SKU库存预占标准能力。主要通过“库存扣减逻辑管控及数据库层交互”、“缓存层交互”,以及“任务调度”三个关键应用,承载库存逻辑计算及存储层交互能力。

数据模型视角,对预占能力实现分为两种:

▪事业部维度库存预占主要通过Redis缓存层承载。

▪批次库存预占直接由数据库承载。

当大促仓配单量进入爆发期,热点SKU预占请求快速增长,且库存预占请求直达数据库,系统TP99会出现跳点甚至持续升高,严重情况下造成接单超时。

以上,计划针对性构造压测场景及数据模型,确认系统的峰值承载能力及调优策略的有效性。

2、首压及分析

压测目标:“库存预占主应用”下的“预占接口”,在数据库承载热点SKU预占请求模式下,探索目标TP99(≤3000ms)可承载的峰值流量,并验证调优后的峰值承载能力(目标 TP99≤500ms)。

压测方案:单个热点SKU持续发压预占,发压起始QPS=10,并以QPS+10递增,探索可承载请求的性能上限。

压测过程及结论

▪在QPS=50时,系统可稳定支撑库存预占业务(TP99≈100ms)。

▪“库存预占”主应用:CPU使用率≤15%,内存使用率≤35%

▪“库存扣减逻辑管控及数据库层交互”应用:CPU使用率≤18%,内存使用率≤65%

▪数据库:CPU使用率≤7.8%(无慢SQL)

▪基于当前的系统性能体现,具备持续加压的条件。

▪以QPS+10递增加压至60时,TP99在2分钟左右快速增长至7000ms,“库存预占”主应用TPS≤60,预判系统能力达到瓶颈,停止加压。

“库存预占”主应用 TP99+TPS趋势

“库存预占”主应用 硬件资源趋势

数据库 关键指标(CPU)

数据库 关键指标(慢SQL)

数据库 关键指标(内存)

瓶颈预判:单据维度的库存预占是以先查(可用库存)后写(预占库存)的方式进行,在对热点SKU高频次下单过程中,数据库会对该行记录长时间持续读写,数据库层面会通过行锁机制保证单笔交易的原子性,行级锁引发的锁竞争大概率会导致系统处理能力达到瓶颈,制约系统的执行效率。同时从应用层到存储层,未出现硬件资源瓶颈,排除硬件资源不足的影响。

3、调优及复压

存储层改造见 库存中心-库存预占场景 系统架构简图):经首轮压测及分析,为解决已知性能瓶颈,从数据架构层面,将批次库存预占由数据库直接承载请求压力,升级为由Redis缓存主要承载请求压力。利用Redis高性能吞吐能力,解决并发场景下的数据读写效率问题,由Redis前置承载热点商品的主要流量。

一致性保障见 库存中心-库存变化监控机制简图

▪为确保缓存层与数据库层数据一致性,在缓存命中的情况下,通过建立调度任务或MQ方式异步回写数据库。

▪在缓存击穿时,通过先读(数据库)后写(Redis)再反馈(API)预占结果,之后异步回写数据库,确保数据一致性。

库存中心-库存预占场景 系统架构简图

库存中心-库存变化监控机制简图

复压结论

▪完成数据架构升级及热点SKU缓存预热后,初始QPS=1100并以100递增,TPS上探至1200时,TP99≈130ms,系统可稳定支撑批次库存预占业务。

▪当TPS上探至1300时,TP99出现明显波动(毛刺≈420ms),且“缓存层交互”应用CPU占用率飙升至90%+,核心链路稳定性劣化,停止加压。

▪相较数据库承载模式,缓存化升级后,TP99满足预期(≤500ms),TPS承载能力大幅提升2300%=(1200-50)/50。

“库存预占”主应用 TP99+TPS趋势

“库存预占”主应用 硬件资源趋势

数据库 关键指标(CPU)

数据库 关键指标(慢SQL)

数据库 关键指标(内存)

Redis集群 关键指标

4、系统健壮性思考

◦**全量缓存的弊端:**供应链模式中的不同行业,SKU品类生命周期存在较大差异(如服饰行业≈3个月),全量缓存模式会导致Redis中存在大量无效品类,资源消耗膨胀不可控,增加资源成本,有必要设计更有效的缓存方案。

◦**缓存预热及保温的必要性:**缓存命中率,与预热机制和保温策略紧密相关。

▪必要性:常规大促节奏,起售期会触发首次缓存初始化,促销品类与日常销售品类的重合度,决定了首次缓存击穿的概率。目前的Key有效期=7天,大促起售期→开门红→高峰期间隔均大于7天,缺少必要的保温策略,会增加下个促销节点前缓存失效的可能性。

大促开门红至11.11 缓存命中率趋势

系统整体可平稳承载流量,__同时缓存命中率曲线,有一定的提升空间

▪预热思路:如何尽可能保持在大促等特定时段的缓存有效性,提升缓存命中率(降低击穿概率),可通过前置的多维度分析调研,包括但不限于基于大数据的大促前集中采购品类分布分析、历次大促及关键节点促销品类密度及分布分析 以及 关键客户促销计划调研等方式,结合技术手段,前置预判、预热及保温。

◦**缓存预热实践:**通过对某客户大促前集中采购期及大促节点SKU品类重合度分析,发现以下规律

▪集采入视角:大促集采期SKU品类,相对开门红品类重合度≈69%,相对11.11品类重合度≈75%。

▪销售出视角:起售期SKU品类,相对开门红重合度≈94%,开门红相对11.11品类重合度≈75%。

▪以上数据证明,通过在开门红以及11.11大促等关键促销节点前,将集采期及前一促销期的SKU可用库存数据,进行缓存预热,有助于提升预占请求的缓存命中率。

大促主要环节 SKU品类重合度分析

◦**异常场景识别:**库存场景对数据三性(准确性、及时性、完整性)要求较高,在数据库与缓存的双向同步过程中,需避免因一致性问题引发的业务异常。

▪超卖异常识别:大促单量峰值期,为保护主数据库安全,通过缓存同步限流减缓主库压力,造成缓存至数据库同步延迟,同一SKU在数据库层未及时扣减,如此时叠加缓存Key到期情况,接口直接返回MySQL数据,可能会引发超卖业务异常。

▪系统优化思路

▪静态方案:单量高峰期期间,延长Key效期,覆盖大促关键环节间隔。

▪动态方案:增加热点SKU缓存效期延时策略,Key到期T-1天,日均预占请求量大于1的SKU,自动延长Key有效期。

5、测试策略改进思考

场景拓展

▪直播电商模式主流化趋势强劲(2023年前三季度全国直播电商销售额达1.98万亿元,增长60.6%,占网络零售额的18.3%,直播电商拉动网零增速7.7个百分点),相较传统电商,其限时促销模式叠加社交传播扩散属性,单品瞬时流量大,不同促销场次品类重合度更低,促销频次高,对系统性能提出了不同的要求。

▪反推性能测试策略,从平台视角出发,需要尽可能提升选用SKU的多样性,同时降低压测单次请求SKU的品类重合度,识别真实复杂场景下的性能隐患。

效率提升:复杂场景的仓配订单性能测试工作,需要前置基础数据的大量储备(商品、库存),以及高复杂度接口请求数据准备。如何确保商品和库存等基础数据快速就绪?同时下单请求的报文体根据SKU密度和复杂度需要,自动化快速构建组装?需要在现有压测框架基础上,开发扩展功能,以支撑从基础数据到复杂单据的一键快速初始化构造能力,降低复杂场景构建难度,提升测试工作效率。

三、无效调用量分析、识别及调优实战

在性能测试的流量分析阶段,结合业务场景调研,前置识别性能瓶颈疑点。

推动排查及调整核心链路调用逻辑后,在标定的业务窗口期,核心接口调用总量降低60%↓。

深入细分业务场景,推演潜在的调优空间。

1、背景

物流系统在订单出库后,由 订单明细查询应用,提供订单及其关联包裹明细信息的对外查询能力。主要由外部系统(Top2量级调用方:接入回传67%、履约回传11%)调用,在单据出库后,输出出库货品的数量和包裹详情等订单基础信息。

关键(Top2)调用方拓扑

2、场景调研及疑点识别

场景调研及风险预判(生产流量分析)

▪对“订单包裹明细查询接口”进行调用量趋势分析,取样23年10.12 06:30~23:00(流量分析期),环比最近一次促销同时段(最近一次大促请求高峰期),Top2调用方峰值调用总量激增305%。

▪基于前期调研,从调用量看,常规情况下仓库出库能力均值≈400000单/分钟,仓库出库高峰时段为每日08:00~18:00,仓出库次数:“订单包裹明细查询接口”峰值调用量≈1:10为“常规比例”。

▪通过对10月12日线上数据观测,仓出库次数:“订单包裹明细查询接口”调用峰值(400000/6532200)≈1:16,相较“常规比例”偏差较大。

▪以上,通过生产流量分析工作,识别出在仓库出库高峰时段,“订单包裹明细查询接口” 调用量存在疑点,并进一步深入分析。

最近一次促销期 关键应用调用量

2023年10.12 关键应用调用量

调用链粗筛

▪仓配出库单据维度,履约回传应用,向订单系统推送出库明细时,会调用仓明细查询接口。

▪接入回传应用,在回传订单信息时,会调用仓明细查询接口。

▪履约状态回传调用峰值 / 接入回传调用峰值 ≈ 1:9,接入回传调用峰值明显偏大,逐步锁定疑点系统(接入回传应用)。

疑点深剖

▪经深入排查,首先确认前期对异常流量和疑点系统的判断基本准确。

▪技术架构层面,接入回传应用在未判断订单状态情况下,调用目标接口。导致单据在未出库且没有出库明细时,发生大量无效调用。

▪同时发现,因AB测试环境别名配置错误,导致生产流量误叠加。

3、调优策略

◦调用逻辑调整

▪“I” 业务场景订单回传阶段,如单据状态为出库前,不发起“订单包裹明细查询接口”调用,剔除无效查询。

▪根据最终的回传内容(是否需要明细信息),判断调用的必要性,剔除非必要查询。

◦调整AB测试环境别名配置,避免测试流量对生产环境产生非必要压力。

优化前接入回传应用逻辑

优化后接入回传应用逻辑

4、调优效果

◦相对调优前(10.12),“接入回传应用” 调用总量降低60%↓(前:2397252500 后:925890100),峰值调用量降低64%↓(前:5921500 后:2121800)。

下图分别为调整前、后调用量分布,用以对比

5、性能风险前置识别

◦压测实施阶段不是发现性能隐患的唯一阶段,如果有能力在流量分析阶段识别性能风险并推动论证,问题发现越早,风控代价(资源)越小,质量风险越低。

6、OpsReview常态化

◦流量异动观测:流量分析及性能风险识别,需要结合实际的生产运营特征,以及接口的关键调用链,定义系统调用量的普遍规律。被调用方有必要不断积累识别调用来源和常规量级,盘点外部调用策略,在调用量出现异动时,排查风险。

◦编码规范:对于接口调用逻辑,有必要抽象为标准方法,避免团队协同开发过程中出现因人而异的Coding差异,降低无效查询发生概率。

◦定制化逻辑排查:系统内非标业务存在较多的定制化逻辑,有必要针对特殊逻辑排查无效查询风险。

7、潜在调优空间推演

◦基于测试经验,经过业务场景梳理,发现 “I场景” 下存在细分的非标定制化流程,以及与 “I场景” 并列的 “P场景” 标准流程。

◦联动研发深入分析 “I场景” 中的非标定制化流程 以及 “P场景” 中的标准流程,已确认,存在进一步优化空间,并明确优化方案(如下图)。

四、总结

性能测试作为系统能力巩固升级的关键措施,通过对典型案例的陈述和思考,探索系统能力和性能测试策略的提升空间。确保核心系统链路稳定高效承载业务峰值流量,同时从容应对极端场景。

作者:京东物流 刘锐等

来源:京东云开发者社区 自猿其说 Tech 转载请注明来源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/596489.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Matrix剪切clipPath缩放scale图片postTranslate圆形放大镜,Kotlin(1)

Android Matrix剪切clipPath缩放scale图片postTranslate圆形放大镜,Kotlin(1) 实现查看图片的放大镜,放大镜随着手指在屏幕上的移动,放大镜里面展示手指触点为中心、半径长度的圆形放大后的图片。 剪切出一块圆形Path…

基于微信小程序的停车预约系统设计与实现

基于微信小程序的停车预约系统设计与实现 项目概述 本项目旨在结合微信小程序、后台Spring Boot和MySQL数据库,打造一套高效便捷的停车预约系统。用户通过微信小程序进行注册、登录、预约停车位等操作,而管理员和超级管理员则可通过后台管理系统对停车…

13.Go 异常

1、宕机 Go语言的类型系统会在编译时捕获很多错误,但有些错误只能在运行时检查,如数组访问越界、空指针引用等,这些运行时错误会引起宕机。 一般而言,当宕机发生时,程序会中断运行,并立即执行在该gorouti…

Vue2 - diff 原理(动图演示)

目录 1,diffdiff 的时间点 2,_update 函数3,_patch 函数(进行 diff)3.1,根节点比较3.2,子节点比较 4,key的问题举例1举例2 1,diff 解释:对比新旧虚拟DOM树&a…

软件测试基础理论学习-软件测试方法论

软件测试方法论 软件测试的方法应该建立在不同的软件测试类型上,不同的测试类型会存在不同的方法。本文以软件测试中常见的黑盒测试为例,简述常见软件测试方法。 黑盒测试用例设计方法包括等价类划分法、边界值分析法、因果图法、判定表驱动法、正交试…

神经网络:经典模型热门模型

在这里插入代码片【一】目标检测中IOU的相关概念与计算 IoU(Intersection over Union)即交并比,是目标检测任务中一个重要的模块,其是GT bbox与pred bbox交集的面积 / 二者并集的面积。 下面我们用坐标(top&#xff0…

数据结构与算法之美学习笔记:44 | 最短路径:地图软件是如何计算出最优出行路径的?

目录 前言算法解析总结引申 前言 本节课程思维导图: 我们学习了图的两种搜索算法,深度优先搜索和广度优先搜索。这两种算法主要是针对无权图的搜索算法。针对有权图,也就是图中的每条边都有一个权重,我们该如何计算两点之间的最短…

Docker安装Elasticsearch,kibana,ik分词器

安装elasticsearch 下载elasticsearch,查看版本:Elasticsearch Guide [8.11] | Elastic docker pull elasticsearch:7.17.16 查看镜像是否下载成功 docker images 创建网络,因为需要部署kibana容器,要让es和kibana容器互联 …

Spring——Spring基于注解的IOC配置

基于注解的IOC配置 学习基于注解的IOC配置&#xff0c;大家脑海里首先得有一个认知&#xff0c;即注解配置和xml配置要实现的功能都是一样的&#xff0c;都是要降低程序间的耦合。只是配置的形式不一样。 1.创建工程 1.1 pom.xml <?xml version"1.0" encoding…

2024 AIGC 应用层十大趋势;iPhone 遭史上最复杂攻击!丨 RTE 开发者日报 Vol.119

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

数据库分区分表

分区分表 为什么要分库分表 软件时代&#xff0c;传统应用都有这样一个特点&#xff1a;访问量、数据量都比较小&#xff0c;单库单表都完全可以支撑整个业务。随着互联网的发展和用户规模的迅速扩大&#xff0c;对系统的要求也越来越高。因此传统的MySQL单库单表架构的性能问…

【 RF 射频 电缆】 MIL-C-17F 标准 规格

第〇、&#xff1f;&#xff1f; RGXXXXX 第一、应用场景 标准号应用场景–&#xff08;–&#xff09;RG-8 RG-9 RG-11粗缆以太网–RG-58细缆以太网–RG-59 RG-75电视系统–RG-62ARCnet网络和IBM 3270网络–RG142电信设备之间的互连 航空电子机架 雷达 GPS 医疗–RG178通信…

Spring常用注解及模拟用户登录流程示例

注解 Resource注解实现自动注入 (反射)代码块xml配置文件 Autowired注解实现自动化注入代码块xml配置文件 扫描器-四个注解Dao层-RepositoryService层-ServiceController层-Controller测试任意类-Component 常用注解示例-模拟用户登录配置自动扫描的xml文件实体类Userdao层消息…

几个有趣的go服务框架

开篇先吐槽几句&#xff5e; 我个人有一些习惯&#xff0c; 比如在服务设计时会考虑的比较长远&#xff0c;会考虑到到未来的扩展等等…然后程序设计的抽象成度就会比较高&#xff0c;各个模块之间解耦&#xff0c;但这样往往就会带来程序的复杂度提升。 这其实在一些公司里面…

微信小程序 ---- 通过 URLScheme 或 URLLink 从短信、邮件、微信外网页等场景打开小程序

1. 用于短信、邮件、网页、微信内等拉起小程序的方法 《URL Scheme 拉起小程序》《URL Link 拉起小程序》 2. 功能描述 URL Scheme: 该接口用于获取小程序 scheme 码&#xff0c;适用于短信、邮件、外部网页、微信内等拉起小程序的业务场景。目前仅针对国内非个人主体的小程…

奇技淫巧:如何给项目中的RabbitMQ添加总开关

本文主要分享了如何给项目中的RabbitMQ添加总开关&#xff0c;通过简单配置开/关RabbitMQ。 一、需求背景 SpringBoot项目里使用了RabbitMQ&#xff0c;但某些场景下&#xff0c;不希望项目启动时自动检查RabbitMQ连接 例如&#xff1a; 在开发不需要RabbitMQ的功能过程中&…

WEB:探索开源PDF.js技术应用

1、简述 PDF.js 是一个由 Mozilla 开发的开源 JavaScript 库&#xff0c;用于在浏览器中渲染 PDF 文档。它的目标是提供一个纯粹的前端解决方案&#xff0c;摆脱了依赖插件或外部程序的束缚&#xff0c;使得在任何支持 JavaScript 的浏览器中都可以轻松地显示 PDF 文档。 2、…

C语言中指针变量如何使用

一、指针变量的定义与声明 1.1 定义 指针变量是用来存储另一个变量的内存地址的变量。在C语言中&#xff0c;指针变量的类型是指向某个类型的指针。例如&#xff0c;int *p; 表示一个整型指针变量p。 1.2 声明 指针变量的声明分为两种形式&#xff0c;一种是直接声明&#…

linux-磁盘扩容 -- 小黑日常超细教程

hi~ 这次小黑带来的是linux磁盘扩容超细教学&#xff0c;按照步骤来&#xff0c;超容易~ 目录 模拟实验对象&#xff1a; 1、查看磁盘分区和挂载点 2、查看新增磁盘 3、将新磁盘格式化&#xff0c;建立新分区 4、查看vg卷组信息 5、分区添加卷组 6、扩容 问题&…

Android kotlin build.gradle.kts配置

1. 添加 maven 仓库 1. 1. settings配置 1. 1.1. settings.gradle repositories {maven {url https://maven.aliyun.com/repository/public/}mavenCentral() }1. 1.2. settings.gradle.kts repositories {maven {setUrl("https://maven.aliyun.com/repository/public/…