服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

电商交易场景状态机方案探索及应用

日期: 来源:闲鱼技术收集编辑:鲲鸣

背景

目前闲鱼行业产品有回收、寄卖、验货宝等,这些产品在基础交易模式上引入附加玩法规则,其状态机相比于普通交易模型更加灵活复杂。基础交易模型订单状态只包含:创建订单->付款->发货->确认收货 。以回收举例,在中台基础交易模型之上,又附加了诸多行业业务状态,如服务商收货、质检、用户确认质检等。这些状态,是通过用户或服务商等多种角色推进的,而业务状态的维护也需要闲鱼自己来负责。

存在问题

目前,在状态履约的代码逻辑实现上,状态履约方法内使用IF-ELSE的结构来判断不同履约动作。在不同的分支里,根据推进节点的不同,存在不同的参数校验、业务执行等等操作。这种原始的实现方式,随着业务的不断发展,逐步暴露出以下问题:

  1. 1. 代码接口复杂:目前回收业务推进某一个单一状态的代码就已经达到上百行,如果把整个状态拓扑的所有履约逻辑都写到一起的话,则整个履约方法将达到上千行,代码内聚高、可读性差。

  2. 2. 模板式代码冗余、无复用:如前置校验、后置消息等。

  3. 3. 无整体拓扑视图:回收场景的这一套代码完成后,之后的开发、服务商、测试都不能感知整体的一个拓扑逻辑。现在我们只能使用另外准备的拓扑图去作为解释文档,但代码上是没有能力直接把整个拓扑提取出来的。

  4. 4. 可扩展性差:如果要增加状态或者删除状态,或者是增加一条履约的边。那么开发人员都需要去改if-else。并且开发改起来的时候必须非常的小心谨慎。比如说要加一个状态,那首先需要整体增加一个else代码块。另外,在每一个之前IF-ELSE分支里面又需要加上判断逻辑,单独处理新加的状态是否可以做迁移等等,所以扩展性是极差的。

此外,横向来看,在行业交易的不同产品下,还存在许多共性需求:

  • • 状态拓扑查询:在服务商接入、测试回归等场景,都需要查询当前业务的状态拓扑,以知道当前订单允许推进到哪些状态。目前只能依靠另外编写对接文档的方式进行沟通。代码没有直接提取状态的能力,有可能导致了对接文档的滞后性。

  • • 状态履约执行:在实际线上履约、对接联调、代码开发、测试回归场景中,都需要执行状态的履约。另外,在不同的场景中,又希望有单独的定制功能,比如:在开发、测试过程中,只能推进测试订单,不能推进实际订单。

  • • 履约记录复现:对于一笔订单的状态推进记录可以复现,以帮助技术、运营、客服定位问题。

  • • 履约日常监控:对不同的业务,可以统一提供履约结果的监控,业务也可能根据自身需要单独配置监控和报警。

解决方案

业界状态机方案调研

业界几款流行的开源状态机框架(如spring-statemachine、 squirrel、smart-engine),均适用于典型的通过状态机管理系统状态的场景,他们的共性特点是:

  1. 1. 通过状态机的定义,表达整个系统状态、控制系统的复杂流转。

  2. 2. 提供xml、或链式调用等方式定义状态机,解决复杂状态机定义可读性差的问题;

  3. 3. 每个状态机需要维护一个实例(对象);

  4. 4. 状态机对象一般是一个单例的、共享的变量,供整个系统访问。状态变换时需要加锁控制并发。

这几款状态机框架通常受管理的对象需要连续的、较长时间的进行跟踪管理,并伴随其完整的生命周期。不适用于订单履约处理,原因是:订单履约方法一般是无状态的,内存不需要对每个处理的订单生成状态机实例。多笔订单对应多个履约请求、多个线程并发调用履约方法。我们的需求是做一个轻量级的、仅仅用来支持行业交易履约的场景, 开发同学通过简单的api就可以定义好拓扑、实现最基础的一两个接口就可以直接运行,监控、日志能力甚至开箱可用。

问题抽象

针对上节最后提出的问题,我们用抽象的思维,思考在状态流程履约中,哪些是不变的点、哪些是变化的点。

可以看到,不变的操作有:

  • • 状态校验

  • • 参数校验

  • • 履约执行

  • • 后置逻辑

这几个操作,都是每个状态的履约中,可以抽象的操作步骤,是不变的点。每个步骤中的实现细节,是根据不同业务变化的点。那么,我们将不变的流程模板化、将变化的逻辑接口化。

状态流程处理

通过一个Executor模板化的执行每个状态履约动作的步骤,如前置判断(validate)、执行状态动作(action)、后置动作(postAction)。对于不同的履约执行动作,抽象出PerformProcessor接口,交给业务具体实现。在某个履约流程执行时,Executor会执行对应的PerformProcessor。

拓扑抽象

对于拓扑定义以及状态流处理定义,进行以下抽象:

状态流程处理器

下面我们来看下状态流程处理器PerformProcessor。它是一个接口,
PerformProcessor中定义了以下几个方法

  • • init: 初始化流程处理上下文

  • • validate:校验入参

  • • action:执行流程转换动作

  • • postAction:执行后置逻辑

  • • finalize:执行收尾工作(本方法一定会被执行,无论其他方法是否抛异常)

如上图,Executor执行器中,会模板化的调用这些方法。

拓扑定义

我们期望定义一个简明易用的API,来将状态拓扑以及履约处理器串联在一起,完成整个状态机的定义,示意如下:

整体框架结构

框架包含三层:核心层、胶水层、业务层。核心层提供纯粹的状态机定义、拓扑构造、执行引擎等能力,设计的薄一些,控制架构防腐化;胶水层引入中台订单查询、更新等能力,相对厚一些,简化业务适配成本、优化业务流程。业务层则基于通用的框架接口,面向业务应用,提供表达能力。

框架核心层
聚焦于三个能力:状态拓扑定义、拓扑查询、状态推进。
状态拓扑定义对应 FlowBuilder。拓扑查询和状态推进对应核心层的 FlowManager,他会查询FlowDefination(拓扑定义封装类) 和 调用 FlowExecutor 执行 PerformProcessor。
胶水层
在状态机核心层和业务交互层之间,我们抽取了一层胶水层。目的有两个

  1. 1. 抽取胶水层,可以让状态机核心层更纯粹,只关心状态履约的定义、流转逻辑,不耦合业务依赖。核心层将相关的信息定义为泛型,也是这个道理。因为入参、出参、履约上下文不影响状态机的流转逻辑,所以核心使用泛型定义。具体类型由上层实现。另外,胶水层中也可以做一些业务相关的通用动作,如记录状态转换日志等。

  2. 2. 可扩展:该层目前使用TC的BizOrder信息,供闲鱼订单业务使用。但如果需要扩展,可以另行封装其他胶水层,不影响核心层我们看到胶水层声明了上下文泛型为 BizOrderContext, 该对象中包含TC的BizOrderDO、PayOrder等信息。由于目前闲鱼订单都是依赖中台订单,所以目前回收履约、验货宝履约等都直接使用BizOrder胶水层即可。但如果某个业务实现需要其他领域的DO,则可以水平扩展胶水层。

业务层
最上层是业务交互层,在不同的业务域内,提供不同的履约功能,比如回收、验货宝都会单独封装对应的履约服务。主要能力:

  1. 1. 对外提供业务履约、测试工具、机器人联调等能力,可分别做权限校验等逻辑

  2. 2. 对内基于胶水层,进行拓扑查询、状态推进等动作

配套设施

  • • 订单推单工具:面向日常开发和测试,业务层基于状态机框架,封装了推单工具。针对一笔订单,可自动获取当前业务状态、可履约动作、自定义入参。

  • • 统一日志&监控:基于框架收口的履约入口,可以提供跨业务统一的日志格式,进而搭建统一的、开箱可用的履约日志查询和监控。

总结

通过抽象订单状态履约的通用问题,提出一套轻量状态机解决方案。解决了业务灵活多变带来的诸多技术痛点:1.通过状态机履约处理器的封装,隔离了每个履约动作的业务逻辑, 解决了接口代码复杂、可读性差的问题;2. 业务可将通用的业务处理逻辑、校验逻辑等封装在通用的处理器中,使得相同逻辑可复用,解决了代码冗余、难复用的问题;3. 通过拓扑的抽象,天然的可以获取到业务的整体状态拓扑,对于联调、业务对接等都提供了便利;4. 如遇需求需要调整状态拓扑,只需修改拓扑定义,即可灵活删除或者新增状态拓扑关系。

展望

闲鱼行业交易团队,在闲鱼回收、寄卖、验货宝的交易履约底层,已全量采用本状态机引擎,实现了订单状态的统一履约控制、履约日志回溯、监控能力。而后续基于本框架,履约逻辑自动回归、履约异常定位可视化等应用场景都将持续构建。

相关阅读

  • 极氪汽车 APP 系统云原生架构转型实践

  • 前言Aliware新能源汽车已经成为我国汽车市场再次崛起的关键支柱,随着新能源汽车市场的快速发展,不同类型的品牌造车厂商呈现出百花齐放的态势。极氪汽车是吉利控股集团旗下高
  • 【精彩回顾】2023第九届数慧新年大讲堂2.17下午场

  • 创新模式催化遥感AI产业发展,如何探索国土资源数字经济新范式?业务能力实现的方法和过程在自然资源领域该如何进行?IBM这些年又提出了哪些数据治理方法和实践?自然资源数据治理
  • 交易所城投债审核反馈问题分类分析

  • 来源:公众号,合规小兵交易所城投债审核反馈问题分类分析作者:方晓一、城投企业债务融资基本情况•(一)城投企业内涵根据经济学上的解释:“城投企业是指地方政府及其部门和机构等通
  • 每周勒索威胁摘要

  • 2023.2.11~2023.2.17每周勒索事件相关情报1. 奥克兰市遭遇勒索攻击进入紧急状态2. Play团伙公布新的受害公司3. LockBit团伙公布新的受害公司每周勒索事件相关情报 1.奥
  • 来,真诚聊几句

  • 全篇内容,无广告,就是几句真心话,希望大家看到最后。大家好,我是Ray,工作十余年,在IBM、德勤等外企做过技术管理与咨询顾问,后来在创业公司以及互联网大厂带过技术团队和数据团队。
  • 突发!高德地图将与饿了么到店业务合并

  • 报道数字经济 定义转型中国现场摄影/泰伯网 萌长撰文 | 程子筠编辑 | 路也泰伯网讯,今日晚间有消息称,阿里巴巴生活服务板块下饿了么到店业务(原“口碑”)将与高德合并,原到店业
  • 解码中国电力调度最大一朵云建设始末

  • 8时15分,在南方电网一条千伏特高压直流线路上,电网运行中一个断面越限问题(处置不当可能会导致大规模停电)被调度员毫不迟疑地解决了。TA的手法很干脆,通过调整了调度范围内一个

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四

最新文章

  • 电商交易场景状态机方案探索及应用

  • 背景目前闲鱼行业产品有回收、寄卖、验货宝等,这些产品在基础交易模式上引入附加玩法规则,其状态机相比于普通交易模型更加灵活复杂。基础交易模型订单状态只包含:创建订单->付
  • 我们这样做容器分层性能测试

  • 前言目前闲鱼不少业务正在从H5/Weex升级到Kun(基于W3C标准&Flutter打造的混合高性能终端容器),从测试角度来看,我们希望这种升级迭代对于用户体验是正向的,所以用好性能测试这把
  • 12月知识小报|线上问题的抽丝剥茧与一锤定音

  • 海恩法则是德国飞机涡轮机的发明者帕布斯·海恩提出的一个在航空界关于飞行安全的法则。每一起严重事故的背后,必然有29次轻微事故和300起未遂先兆以及1000起事故隐患。作为
  • Windows平台Flutter桌面应用的底层模块化探索

  • 前言Windows应用开发有着较为丰富和多样的技术选型。C#/WPF 这种偏Native的闭源方案,目前开发人员相对比较小众了。C++/QT 的跨平台框架,C++对于GUI开发来说上手会更难。JavaS
  • 浅谈任务分发中的机制与并发

  • 导言任务模型的抽象具有广泛通用性的,例如饿了么骑手每笔骑单是任务,小法庭中交易纠纷的评审也可以被抽象为任务。下面是简易的任务系统模块图,图示中去除了上下游的模块,保留了