业务总结004:检验项目时间轮实践与库存实现方案
2020 年底公司和阿里健康合作了一个检验项目,由我司提供检验项目(商品)、采样点(商户)、库存等底层数据,与阿里健康开发对接后在支付宝平台进行线上预售,开发流程其中也包括订单数据的交互。
项目开发期间踩了比较多的坑,做了很多优化,其中也包含一些有意思的技术实现方案。
一、时间轮实践
某些业务场景下,我们需要频繁调用阿里健康接口,项目第一个版本上线后,发现有部分请求触发阿里健康接口流控告警,原因是他们提供的接口在一定的时间内只允许 N 次接口调用。针对这个问题,想到了以下几种实现方式:
- sleep 同步调用:对批量数据进行拆分,每条数据都 sleep 一段时间
- ScheduledExecutorService 异步调用:延迟任务,通过线程池调度
- HashedWheelTimer(Netty) 异步调用:将批量数据按照一定延迟时间添加到时间轮队列中,等待调度
第 1 种方案如果同步批量数据过多,sleep 后客户端一直得不到响应,直接 pass。第 2 种方案需要频繁的创建和销毁线程池,考虑到客户端交互频繁,选择了时间轮方案。
当有任务添加到队列中后,Netty 时间轮会开启一个工作线程,后续所有任务的执行都依赖这个线程,因此不会频繁创建与销毁线程资源。但是有一个缺陷是当没有任务时,这个线程会一直空转,只要不同时存在多个时间轮,这个空转是可以接受的。
Netty 时间轮原理如下:
关于 Netty 时间轮设计原理,可以看下我这篇文章的总结:Netty 时间轮原理分析
二、检验项目库存实现方案
2.1 库存预生成方案
刚开始的库存设计方案比较简单,运营人员先在后台绑定采样点与检验项目的关系,然后设置排期和具体日期对应的库存,后端接收到数据后直接入库。
由于是在线预售业务,一般会对未来一个月内的日期进行排期。如果有 X 家采样点,一家采样点绑定了 N 个项目,排期天数设置为 M 天,就需要在数据库中保存 X * N * M 条记录。随着时间推移 M 越来越大,数据量也就越来越多。
这种设计方案比较容易理解,和订单交互的流程也比较简单,但是有一个很严重的问题是会预生成大量的库存数据,业务发展不到两个月就已经生成了 200w+ 的数据量。
对这些数据进行分析后发现 95% 的数据都是无用的,于是想了以下两种方案解决这个问题:
- 预先生成逻辑不变,通过定时任务扫描库存表,删除无效数据,无效数据主要指非未来时间且没有库存变更的数据
- 延迟生成库存,当未发生库存变更请求时不生成库存,针对查询操作,通过业务代码构造库存信息,当库存变更时延迟生成库存
第一种方案实现比较简单,原先的业务逻辑不变,只需要定义一个库存清除任务即可。当删除 MySQL 表数据时,这些数据所占用的空间可能会被标记为可复用,并不会释放磁盘空间,出于这个考虑选择了第二个方案。
2.2 延迟库存生成方案
延迟库存生成流程图如下:
采用延迟设计方案后,数据量至少减少了 95%,考虑到并发情况,库存延迟生成时需要利用分布式锁防止创建多条库存数据。
库存延迟生成虽然解决了数据量的问题,但是针对一些特殊的产品需求,比如:修改某一天的库存,需要保存运营现场数据,处理起来会比较复杂。最好的方式是权衡各个方案的利弊,找一个适合业务发展的方案。
2.3 库存分时
后来和阿里健康对接了一个上门服务业务,这个业务起来了,单量也越来越多,退单率也高了起来,甚至收到了比较多的客诉,原因是用户只能约某一天的订单,但是并不知道线下人员什么时间段上门。
有的客户约了明天的订单,但是客户可能只有明天上午有时间,线下人员如果下午上门服务,这时候客户就不高兴了,不高兴了怎么办,总得找个方式发泄,投诉。
为了解决这个问题,阿里健康团队提出了分时策略,将一天划分为几个时间段,比如:上午十点到十二点,下午两点到四点。这样客户有更多的选择,尽可能避免出现上面投诉的问题。
2.4 库存模型
- 库存策略:分时与不分时是两种策略,支持来回切换
- 库存日期模板:库存未生成时,需要根据库存日期模板信息与分时策略构造库存信息
- 库存:库存实体
- 库存流水:记录库存变更,便于排查问题与库存核对
三、总结
沟通与表达至关重要,保持良好的沟通往往能节约大量的开发成本并减少线上问题。
设计库存模型时由于时间紧迫,没有具体讨论相关设计方案,目前库存相关表设计不够扁平化,当后期处理延迟改造与分时项目时,有的细节实现起来比较复杂,需要冗余一些信息,导致代码复杂度高,可读性下降,因此需要在代码中批注相关注释。
库存变更存在并发问题,延迟生成时通过分布式锁进行控制,库存扣减与回退时有以下处理方案。应该综合考虑并发程度与用户体验,选择适中的方案。
- 利用分布式锁,代码层面对库存进行计算,更新 DB
- 对库存变更流程进行事务控制,利用数据库拍他锁通过 DB 计算扣减与回退库存
- 库存放到 Redis,Redis 扣减成功后再操作 DB
- 利用数据库乐观锁,进行版本号对比
库存核对,可以开发自动化库存核对脚本,以任务的形式自动核对。
业务总结004:检验项目时间轮实践与库存实现方案相关推荐
- 时间轮 (史上最全)
缓存之王 Caffeine 中,涉及到100w级.1000W级.甚至亿级元素的过期问题,如何进行高性能的定时调度,是一个难题. 注: 本文从 对 海量调度任务场景中, 高性能的时间轮算法, 做了一个 ...
- 网站项目成功管理实践(刘振飞)
网站项目成功管理实践 刘振飞 -发表在<程序员>杂志2005年第8期58~62页的原文- 在开始做http://133.newsky.cn之前,我已经明白网站的开发与产品开发没有什么不同. ...
- 最详细大数据项目落地路线图实践总结
今天,来谈一谈"大数据项目如何落地?"这个话题.从事过多个大数据项目的规划方案及项目落地工作,在这里与大家分享一些心得,主要是关于大数据项目如何成功落地并取得预期目标,也可以说这些 ...
- 项目管理理论与实践(1)——企业项目管理介绍
一.企业项目管理的概念 1. 什么是项目管理 这里把"项目管理"关键词拆解为2个词:项目.管理. 项目:为完成某一独特产品或服务所做的一次性努力. 管理:同别人一起,或通过别人使活 ...
- Netty时间轮调度原理分析,再不了解你就out啦
一.时间轮介绍 之前公司内部搭建的延迟队列服务有用到时间轮,但是一直没有了解过它的实现原理. 最近有个和支付宝对接的项目,支付宝接口有流量控制,一定的时间内只允许 N 次接口调用,针对一些业务我们需要 ...
- react打包后图片丢失_React中型项目的优化实践
本文可能涉及的内容-- 项目介绍 整个项目大概有60+个页面,用到的组件大概150+,package里面的依赖大概有70+个,应该勉强算得上是一个中型的React的项目了. 下面给大家看看我们现在bu ...
- react 判断图片是否加载完成_React中型项目的优化实践
项目介绍 整个项目大概有60+个页面,用到的组件大概150+,package里面的依赖大概有70+个,应该勉强算得上是一个中型的React的项目了. 下面给大家看看我们现在build一次项目的结果-- ...
- 前端技术演进(六):前端项目与技术实践
这个来自之前做的培训,删减了一些业务相关的,参考了很多资料(参考资料列表),谢谢前辈们,么么哒 ? 任何五花八门的技术,最终还是要在实践中落地.现代的软件开发,大部分讲求的不是高难度高精尖,而是效率和 ...
- 一个数字几个字节_技术工坊40期-DAG技术特性以及在字节雪球Obyte项目的使用实践...
1. 活动基本信息 1)题目: [区块链技术工坊40期]DAG技术特性以及在字节雪球Obyte项目的使用实践 2)议题: 字节雪球Obyte(原名Byteball):一个基本于DAG技术的去中心化分布 ...
最新文章
- html中单双引号嵌套,[转]详细讲述asp中单引号与双引号(即引号多重嵌套)的用法...
- 面试宝典JAVA集合框架 List、Set、Map
- Nukeygara Akeytsu 2020中文版
- php foreach方法,forEach方法怎么使用
- Flex3双向绑定完善版
- 奇怪的匿名函数之争EventHandler
- 萤石网络摄像头服务器稳定吗,萤石摄像头画面稳定性如何?
- Java FilterInputStream skip()方法与示例
- android 画面俯视效果,四种方法让你的画面更耐看
- 维护2G网络的稳定必须提升到战略高度
- HTML5七夕情人节表白网页制作【唯美满天星3D相册】HTML+CSS+JavaScript
- 160x128JAva_GitHub - hanang128/X-SpringBoot: X-SpringBoot是一个轻量级的Java快速开发平台,能快速开发项目并交付【接私活利器】...
- 电影天堂python分页爬取
- 【Unity】Unity3D RPG游戏制作实例(一)游戏简介及文档目录整理
- 《Learning Enriched Features for Real Image Restoration and Enhancement》
- 汉语拼音的5个声调该怎么学?
- 软件测试阶段划分以及测试分类
- C++库常用函数一览表
- 常见互联网公司职级和薪资一览!有条件的一定要进大厂,薪水是真高!
- c语言的各种规范:C89、C90、C95、C99