一: 产品需求

四个实体,用户、订单、悦姐、店长,自动排单需要把用户下的订单替店长排到悦姐身上。

订单分为周期指定悦姐订单和单笔随机订单。

悦姐库存以半小时为单位,每半个小时算一个槽。

下单时间根据配置来,白天基本都可以下单。

目标: 在订单和悦姐之间寻找最佳匹配

模型:

悦姐: 库存、技能、家庭住址订单:地址、技能、占时硬性约束: 悦姐存在满足的库存和技能
软性约束: 得分(偏好,距离,库存利用率)指标: 悦姐库存技能一定时排订单最多,或者总得分最高,单个门店或者所有门店作为维度

二: 算法及规则实现

定时任务: 每天凌晨按门店+日期的维度进行派单,多轮计算,每一轮取最高得分订单进行派单并在下一轮剔除,共需计算 订单.数量 轮次。

半小时优化: 对于在到门店但是还未派到悦姐身上的订单,进行半小时一次的优化,算法和凌晨定时任务类似。

实时到人: 用户下单后,根据规则实时计算门店悦姐得分,并派单到最高得分的悦姐。

凌晨的定时任务优势在于待排单池中订单多,悦姐身上订单少,每轮取最高分,那么每家门店的订单总得分,将是最高的。

半小时优化会把一些得分低的订单,和有库存的悦姐再进行一次匹配,让总的得分上升。

实时到人是按照用户下单的优先顺序进行派单,所以是实时最优不是一定范围内的最优

三: 自动排单的优化和思考

自动排单第一个版本,只有夜里进行推荐排单,一直优化到白天用户下单,实时分配。
单个订单选择最高得分悦姐,缺点很多,比如 得分受 订单+悦姐身上其他订单 影响,在悦姐身上订单有变化时,得分就会改变,所以最高得分,可能只是那一瞬间的最高得分。
这个优化算是将单个订单局部最优,优化为单个订单整体最优。
后序还可以把相关性很强的订单,作为一组,进行计算,而不是单个单个的订单进行计算。
在技术上,订单数据和悦姐库存,因为有实时性,所以没有缓存,后序可以优化为监听 binlog 实时更新缓存,优化下单时间。

半小时的定时任务优化排单是在白天,而白天用户和店长都会进行操作,所以在重新优化时,不能大面积的锁订单或者库存,这时采用了伪取消,即没有在数据库中改数据,而是在内存中计算时,计算悦姐库存不把这些需要重新优化的低分值订单考虑进去。

在计算悦姐得分时,有三种得分规则,一种是离家距离,一种是悦姐的库存利用率,还有一种是单与单之间距离。
具体得多少分,根据运营配置来获取。在计算规则得分的时候,需要空间换时间,把数据缓存成易于使用的方式,让查询变快。

四: 自动排单使用到的技术点

夜里的定时任务:因为门店之间是不共享悦姐的,所以悦姐库存是独立的,今天和明天的订单之间,也没有关系。所以以 门店+日期 的粒度进行多线程排单,避免了线程间共享数据,是线程安全的。

悦姐库存的锁:不管是哪种方式进行排单,都需要请求悦姐库存,而不同的方式之间,悦姐库存是共享的,这个时候就需要给悦姐库存加锁。如果锁整个门店的悦姐,因为用户下单、店长调整订单、定时任务半小时优化,都比较频繁,粒度就比较大了,因此把加锁延迟到排单入库的时候,入库之前如果拿不到最高分悦姐的库存的锁,就拿次高分,以此类推。

推荐排单日志:记录了订单信息和悦姐信息,有些是实时收集,在获取到信息进行计算时,塞入 ThreadLocal,计算完成入库后,发送事件到 Ringbuffer,在 handle 中异步再补全日志信息,生成排单日志。使用了 Disruptor 来做事件处理。

定时任务线程:使用 metrics + 继承 ThreadPoolExecutor 来监控线程池中任务的处理情况,指标有任务处理时间99 95 线、吞吐量等,并且把线程池的基本信息,比如核心线程数、最大线程数、任务数量、已完成任务数等等透传给外面。

规则计算:使用 QLExpress 作为规则引擎。把表达式缓存在数据库和内存中,达到可以实时调整的目的。

五: 监控与告警

周期计划浪费越界槽位监控:

除了单笔订单还有周期订单,周期订单指定了悦姐,到了配置的时间,自动生成订单,排给指定的悦姐。因为下单时,没有固定的时间,白天所有的时间都可以作为悦姐的开始时间,所以会有很大的库存浪费。基于此种场景,做了一个周期指定计划的检查,根据给定的门店,检查该门店悦姐浪费了多少个时间槽。

算法:计算浪费的时间槽,使用了类似搜索迭代算法。

1.检查悦姐开始计划与库存开始时间
2.检查悦姐身上计划与计划之间是否可以塞入计划
3.检查悦姐结束计划与库存结束时间

检查计划与计划之间是否可以塞入计划伪代码:

dynamicSlotPost(boolean isFirst, int start, int end, CalculationInfo ci, Set<CalculationInfo> paths) {// 是否越界if(isFirst && start >= end) return;// 如果开始时间槽加上计划的时长,大于结束时长,则代表不可以再塞入订单,收集并返回if(!isFirst && checkOverFlowPost(start+ci.getRecommendSlot(), end)) { path.add(ci.copy());return;}//  本次计划开始时间槽和推荐时间信息CalculationOrderInfo coi = new CalculationOrderInfo();coi.setStartSlot(start);ci.getOrderInfos().add(coi);//  两小时的推荐订单if(isFirst && checkOverFlowPost(start + recommendSlot2, end)) return; // 第一次进来是否越界coi.setRecommendSlot(recommendSlot2); // 设置本次计划推荐时长checkAndRemove(ci, end);  // 如果ci中最后一个计划越界了,则剔除后继续迭代dynamicSlotPost(false, coi.getStartSlot()+recommendSlot2, end, ci.copy, paths);//  三小时的推荐订单if(isFirst && checkOverFlowPost(start + recommendSlot3, end)) return;coi.setRecommendSlot(recommendSlot2); // 设置本次计划推荐时长checkAndRemove(ci, end);  // 如果ci中最后一个计划越界了,则剔除后继续迭代dynamicSlotPost(false, coi.getStartSlot()+recommendSlot3, end, ci.copy, paths);}

定时任务线程池监控:
通过继承 ThreadPoolExecutor,重写前置和后置拦截器,来监控任务的执行情况,并且在排单失败的时候,会把异常和订单相关信息通过邮件发送。

监控店长调单率:
通过每次推荐排单的数据库记录,来计算店长的调单率,监控调单率较高的店铺,与店长沟通,获取反馈,优化排单规则。

排单日志:
店长有时候会问为什么排给谁谁谁,并且运营也需要查看排单的计算情况。所以在每次排单的过程中,收集相关数据,比如订单的时间、地址等,和每个悦姐的得分、悦姐的库存、技能、以及被过滤的原因等信息,展示出来。

六: 总结

痛点,库存代码是遗留代码,设计不规范,有多种查询库存方式,订单表和悦姐库存占用表都被用来查询库存了,并且库存在内部使用的时候,没有统一的数据模型,比如库存服务 1 代表可用,规则服务 0 代表可用,推荐排单服务使用时,就必须转换格式。

还有规则服务也是两年前的废弃版本,现在重新启用,没有文档,只能一点一点研究,不过确实比从零开始写快一点。

复盘总结一下,前前后后走了好多弯路,有些是需求不完善,有些是实现的时候没想清楚应该怎么写,代码删了改改了删。

自动排单功能的一些思考相关推荐

  1. java排班_使用java规则引擎Drools自动排班前言.doc

    使用java规则引擎Drools自动排班前言 使用java规则引擎Drools自动排班前言本文以一个经简化的运输车队自动排班需求为例,详细讲解了如何使用java规则引擎Drools进行商业规则的形式语 ...

  2. APS自动排产在五金行业的应用

    五金行业是以离散为主.流程为辅的制造业,生产过程主要是金属加工和部份装配.五金制造主要有:毛坯铸造.冲压制造.机械加工,加工环节包括铸造.锻造.热表处理.原材料分割.铁线折弯.车.铣.刨.磨或钣金成型 ...

  3. 中汽创智科技首席人工智能官丁华杰:AI赋能自动驾驶的几点思考

    2020-12-04 18:05:00 11月14日至15日,由中国人工智能学会.嘉兴市人民政府主办,嘉兴市南湖区人民政府.嘉兴科技城管理委员会.浙江未来技术研究院(嘉兴)共同承办的2020第十届中国 ...

  4. 智能排班系统、班次、班表、考勤、年假、调休、审批、请假、培训、值班、换班、加班、工时、自动排班、智能预测、人力需求预测、授权、团队、锁定量排、规则权重设置、菜单、角色、数据监控、工作台、axure

    智能排班系统.班次.班表.考勤.年假.调休.审批.请假.培训.值班.换班.加班.工时.自动排班.智能预测.人力需求预测.授权.团队.锁定量排.规则权重设置.菜单.角色.数据监控.工作台.axure原型 ...

  5. 的采样方式_DR803M4水质自动采样器(岸边站自动排空型)

    应用概述 该水质自动采样器适用于岸边式水质自动监测站,该采样器可与地表水水质自动监测系统对接,实现定时采样.时间等比采样.同步采样.外控采样.超标采样.立即采样功能.采样瓶具有密封功能.自动排空功能以 ...

  6. 粒子群课设_GitHub - LIYAJUN2018/tscss: 基于粒子群算法的中职自动排课系统

    kvf-admin kvf-admin是一套快速开发框架.脚手架.后台管理系统.权限系统,上手简单,拿来即用.为广大开发者去除大部分重复繁锁的代码工作,让开发者拥有更多的时间陪恋人.家人和朋友. 后端 ...

  7. 自动排课系统V2.0基本完善了

    中小学的自动排课系统2.0完成了,将其命名为王者智能排课系统 ,感觉还不错. 相对于1.1,有如下改进: •实现中小学排课的自动化. •计算机排课+人工辅助的全新排课解决方案. •多种算法可供选择(搜 ...

  8. aps自动排程助企业缩短制造周期

    现在我们都知道精益生产的四个基本目标:一是提高设备利用率:二是降低库存:三是缩短生产周期:四是按时交货.缩短产品制造周期可以大大降低在制品的数量,减少半成品库存,并避免产生半成品呆料. aps自动排程 ...

  9. PHP自动排班系统 源码+说明

    PHP自动排班系统 下载源码时请将"PHP排班系统代码"整个文件夹下载 资源下载链接: https://github.com/Mrjx-best/JX_OPEN. 使用须知 在下图 ...

  10. excel自动排班表怎么做?哪里有免费的自动排班表?2022最新整理30份Excel自动排班表,建议收藏

    你还在手动排班吗?别再这样做了,我有更高效的方法! 在工作中,我们经常需要进行排班,不管是假期值班,还是直播排班,都需要做一个排班表.以前的时候排班都是手动调的,你周一我周二,但这种做法效率比较低,而 ...

最新文章

  1. mysql登录密码特殊字符_mysql密码中有特殊字符在命令行下登录的操作
  2. python中调用多进程加速处理文件
  3. JS使用XMLHttpRequest对象POST收发JSON格式数据
  4. Docker精华问答 | task与executor有什么关系?
  5. 第一部分 线性表的链式存储(三)--静态链表
  6. 树莓派安装TPLINK_WN725n v2网卡驱动
  7. [SOA] Mule ESB 3.x 入门(二)—— 配置(spring, properties, log4j)
  8. mysql dbutil_DBUtil
  9. switch日文键盘打中文_从塞尔达到动森,游戏中使用的中文字体有什么问题?
  10. Win11 DELL - G7 如何开启TPM模块
  11. 移动广告平台KeyMob:整合多家主流手机广告平台
  12. 大白菜装机教程win10_win10安装教程
  13. mysql5.5手册读书日记(2)
  14. 人脸识别行业应用状况及发展前景模式分析报告
  15. 积分和微分电路结构原理带Multisim仿真
  16. angular async和await (实用)
  17. 微信小程序导航栏切换页面
  18. 土壤湿度遥感监测 - 植被指数/地表温度与土壤湿度
  19. 【号外】支付宝道歉,错了就是错了,马云回话
  20. SQL注入堆叠注入二次注入

热门文章

  1. 赵海平专访【2015-03-26】
  2. python证件照换底色_还在用PS给证件照换底色吗?20行代码教你用Python给证件照换底色...
  3. 【Excel VBA】自动调整列宽和行高
  4. 【华为联机对战】下载运行华为官方Unity示例代码,提示鉴权失败并返回错误码100114
  5. wps序号打乱重新排序_WPS中Excel怎么自动排序
  6. word中批量修改上角标、下角标
  7. kettle使用httpClient获取ES索引数据
  8. 欧拉坐标与拉格朗日坐标
  9. Java之——被人遗忘的Java8的八个功能
  10. pytorch转为onnx格式,以及加载模型的params和GFLOPs方法