作为技术人员,最早接触的仿真,是学习基于单片机等嵌入式硬件编程时,使用仿真软件来模拟硬件的行为。自此以后,小到单元测试、大到双十一的全链路压测,都可看作广义上的仿真过程。从中可以总结出,仿真的主要作用:
能够脱离实际时间、空间等条件及情况的限制,低成本的对现有模型进行各种类型的测试,达到优化或风控的目的。
本文侧重电商供应链中业务配置、策略/算法等的仿真,以供应链中采购入仓、仓库间库存调拨、销售订单调度三部分业务(上图)及组合为例:
采购入仓
配置:各商品的生产时间及产能;供应商发货到各仓库的运输时间及费用等。
策略:什么情况及时间、对哪些商品及仓库进行多少数量的采购补货。
目标:控制库存水位,既不缺货(频繁采购、额外调拨及配送成本),也没有过多的库存积压(仓储成本及滞销风险)。
仓间库存调拨
配置:仓库地址;每天各仓能接收入仓的数量;仓库间的车次、车型、运输时间及费用等。
策略:相比采购,更聚焦于内部多个仓库间的准实时库存平衡。
目标:在控制调拨成本的情况下,尽可能减少下游销售订单的配送时间及成本。
销售订单调度
配置:综合考虑各快递各路线配送费及配送时间;各仓库租赁及打包拣货费。
策略:根据用户地址及库存情况,综合上述配置,选取合适的仓库及快递。
目标:在保证用户体验(配送时间等)的情况下,控制成本。
综合起来,三者都对库存进行影响,需要进行策略的协同配合及感知,才能达到整体的最优。
读者可能会联想到,对于互联网其它类型业务,方案评估可以用ABtest。之所以没有采用,是其业务特殊性导致的:
1. 反馈周期长:供应链中的采购、物流等行为都是以天记的。在线上分流验证效率太低;
2. 无法分流量:所有库存是一个大的整体,可以进行跨地区发货及调度,用户的订单,都通过库存对其它用户的订单造成潜在影响,无法完全分隔;
3. 测试成本高:相比于用户访问页面及推荐内容投放等,供应链中的操作直接产生实际费用成本,例如仓库租赁费、运费等。
因此,脱离实际时间空间等限制、低成本的仿真方案成为了更合理的选择。
仿真手段在严选内部进行了广泛的应用,具体可分为以下4种类型:
1.生成模型
在不考虑库存限制下进行订单调度(选择仓库和配送快递)仿真,计算理想情况下各商品在各仓分配量及比例,用于指导采购入仓及仓库间的库存调拨等实际业务运行。
2. 方案调优
通过调整订单调度的策略和参数,优化了成本(仓库拣货费,快递费等)及用户体验(配送时间、是否拆包等)。
3.收益评估
线上会对一定时间段内的同一用户及地址订单进行合并发货。仿真环境使用合单前的订单进行仿真。两版数据对比,即可得出合单收益。
4.风险控制
例如某个仓库发车车次的时间误配置为0,导致大量订单因为配送时间短选择了该车次,引起车次乃至仓库承载量的超出,此类问题可在上线前通过仿真预先发现。
仿真体系的设计与压测有些类似,都需要接入服务部署在独立的环境,使用方构造外在输入,设定并发量,作为一个任务启动运行,并收集统计运行结果。但仿真需求有其特点,表现在3大方面:
1. 用户需要更灵活丰富的自定义空间
除了抓取历史数据,并基于此构造系统调用,设置并发量外。还需要对系统配置参数进行调整及初始化、模拟关键定时任务的触发、对结果进行临时敏捷的数据分析等。
2. 外部输入有较严格的时序需求
牵扯到多类系统且是有状态服务,同时需要数据准确以供评估方案。
3. 多仿真任务并发
由于是对不同配置方案的测试,通常需要跑多组任务进行对比评估。同时出于产出数据指标准确性的限制,不能无限提高单套环境的并发。
因此进行了上图所示的针对性设计,对3个问题进行解决:
用户可自定义轻量级的插件;
进行统一的时序控制;
基于容器编排和服务治理、快速搭建多套独立的仿真环境。
为方便下文理解,简要介绍下相关概念:
是仿真过程的单位,用于一次方案评估需求。
名称 | 含义 |
---|---|
taskId | 区分不同仿真任务的标识 |
[startTime,endTime] | 仿真虚拟时间段起点及终点,用于时序控制 |
env | 任务运行所在仿真环境的标识,可以创建任务时指定,或由平台自动创建调度 |
Map<pluginId,pluginConfig> | 任务所需的插件及插件配置参数的集合 |
scene | 所属业务场景标识 |
(pluginConfig)是仿真任务中所需插件的运行配置信息,可复用。
名称 | 含义 |
---|---|
pluginParam | 用户可自定义的业务相关参数,例如构造输入的策略、初始化配置、统计指标等 |
bufferSize | 存储插件生成事件的缓冲区大小 |
concurrentNumber | 插件消费处理其事件的并发数 |
(SimulateEvent)为仿真任务中的一次用户干预,例如一次外部输入、统计触发、定时任务触发、配置初始化等。
名称 | 含义 |
---|---|
pluginId | 产生并消费该仿真事件的插件标识 |
time | 发生该仿真事件的虚拟时间点 |
action | 事件发生的描述信息,使用泛型表示 |
以下对各部分组件运行流程分别阐述。
只要引入插件框架包,实现以下接口,打包上传到仿真平台(通过统一交互层)即可。在单独容器中运行,以实现与平台的资源隔离。
(以下均为Java版插件实现。针对多语言支持有一套较复杂的http交互,插件框架是对其的封装,以降低开发成本)
接口 | 含义 |
---|---|
Boolean produceEvent(BlockingQueue | 任务启动时根据pluginParam,产生[startTime,endTime]内的事件并按时序put到缓冲区(阻塞队列)中,也可对所在仿真环境服务配置初始化。全部事件产生完或出错时返回 |
Boolean processEvent(SimulateEvent simulateEvent) | 根据时序控制的通知,消费处理对应事件 |
String exportDefaultParam() | 导出默认(通常为线上)配置参数供用户参考调整 |
Boolean checkParam(String pluginParam) | 对参数校验 |
平台的统一入口,包括两方面功能:
插件管理:用户通过其提交插件且设置其是否可用。每个提交且状态为可用的插件,会为其制作镜像,同时启动容器来运行插件服务,用于插件默认配置的导出及校验;
任务管理:任务的crud。用户准备创建任务时,对其引用的插件,调用exportDefaultParam()导出默认配置,用户在此基础上编辑后提交时,调用checkParam检查通过后存储。
实现两部分功能,定时触发:
任务优先级确定调整
维护更新全局以及每套环境的任务队列;
对于指定了运行环境(涉及代码逻辑及特殊资源的方案评估)的任务,提交到该环境的队列中,否则提交至全局队列;
队列内部综合考虑提交时间及业务场景作为优先级,根据其排序。
任务执行环境分配
与各环境的时序控制组件通信,检测每套环境任务执行情况,更新任务状态;
发现环境空闲时,获取全局队列和环境队列中的队头任务,对环境队头任务适当提升优先级后,选取优先级最高的。提交给该环境的时序控制组件执行。
对多个插件产生的事件按序发生,流程如下:
在该环境中为任务所需的插件创建并启动容器,调用其produceEvent产生事件,放入插件缓冲区。插件框架在服务启动时自动在该环境中进行服务注册,并根据配置设置其事件执行线程池及事件缓冲区大小;
所有插件正常启动后,遍历插件,各获取一个最早事件时间,即其缓冲区队头事件时间,进行排序;
对发生最早的事件,通知插件执行。为避免不同业务输入并发时引起的较大误差,若当前事件和上次事件所属插件不同,先轮询所有插件,当所有插件线程池均完全空闲时,再执行当前事件。插件框架会取出缓冲区队头事件,调用插件processEvent(提交到线程池执行),同时返回新队头的事件时间;
时序控制器将该插件返回新事件的时间加入排序,重复3过程;
当事件时间排序区为空,轮询所有插件线程池确定是否均完全空闲。两者都满足说明本次仿真任务完成。停止该环境的插件容器,环境状态变为空闲,同时更新任务状态。
在仿真体系中,除仿真平台因需求特殊需要重新设计实现外,相关依赖尽可能复用了开源及公司内部已有解决方案,主要有4部分
首先基于其,可快速同步进行所有接入服务在线上及多套仿真环境的搭建以及CI/CD。
其次仿真任务运行使用的插件适合基于其实现随任务生命周期而开关,具有以下两点好处:
每次运行期间只用于一个仿真任务,容器终止时自动清除程序内状态,节约了相关开发成本;
每个仿真任务只用到一部分插件,不同任务使用的插件也有不同,因此节约资源。
同时由于插件较为轻量级,启动较快,且没有实时响应的需求。因此也规避了该方案的缺点。
用于在同一套代码的前提下,部署运行多套平行的仿真环境。
数据收集同步至数据仓库并进行数据处理,用于3个方面的应用:
插件使用线上配置数据作为默认模板导出,便于用户在此基础上参考修改;
插件基于线上历史输入请求的记录进行模拟事件的生成;
数据开发任务配合插件,实现基于模拟环境数据的评价指标统计。
对于少量业务配置及算法参数,可直接放在插件配置(pluginConfig)的pluginParam中,存储于关系数据库。
但业务配置,例如快递线路及报价等,一般通过excel交互,且一个插件配置中通常涉及多个业务配置,既不适合直接存储于关系数据库(大量不定长数据),也有额外的格式转换开发成本。
因此对于业务配置的导入,上传至文件存储服务,将其下载链接存放于pluginParam中。导出时请求该链接即可。
仿真是供应链领域常用的优化手段,对于供应链行业从业人员来说,或多或少都接触或进行过仿真,为什么我们还要如上文所述新设计一套方案呢?在做之前,我们也调研了行业的主流方案,都有其各自的优缺点,因此我们没有照搬行业方案,而是新设计了一套覆盖已有方案的优点并补足其缺点的解决方案。对比结果如下:
名称 | 应用方 | 学习成本 | 落地成本 | 通用性 | 覆盖范围 |
---|---|---|---|---|---|
商业仿真软件 | 业务专家,教学科研 | 高,专用软件及语言 | 高,与业务系统分离 | 高 | 业务线 |
离线数据分析 | 互联网电商及物流 | 低,数据开发 | 高,与业务系统分离 | 低 | 单业务 |
算法效果测试 | 互联网电商及物流 | 低,程序及数据开发 | 低,基于业务系统 | 低 | 单业务 |
严选供应链仿真 | 严选供应链 | 低,程序及数据开发 | 低,基于业务系统 | 高 | 业务线 |
在解决评估优化产品策略和方法的过程中。仿真相比ABtest、压测等常用手段,有其独特的优势,能够脱离真实的时间及环境进行全链路的精确模拟评价。但同时业务流程上相对其它手段也更为复杂,包含了大量个性化的需求。
目前我们针对常规手段无法解决的需求,建立了完整的严选供应链仿真体系,且在实践过程中,对业务流程进行提炼总结,独立出了仿真平台,同时具有较好的通用性及扩展性。解决了严选供应链中的建模、优化、评估、风控等诸多问题。同业内其它供应链仿真解决方案相比,也具有特点及优势。
未来我们会在纵向上深入进行现有仿真体系及平台的功能增强,进行更智能及自动的仿真评价及优化风控。同时在横向上寻求更多业务乃至供应链以外的应用场景及落地。
吴航,2017年加入网易,负责严选供应链仿真体系的建设,以及时效生产、建模优化、异常检测等业务。从无到有搭建了仿真平台,主导了供应链业务线的接入及落地。曾就职于优酷土豆。