本文系统介绍了基于有限状态机的广告状态管理方案及实现,希望对大家有所帮助和启发。
乐高平台是58同城的中台商业系统,负责58同城的在线广告业务,其中的乐高投放平台主要服务于58同城的广告主。乐高投放平台的广告状态维护是一件重要且复杂的事情,将问题抽象化之后就转变成了基于有限状态机(FSM)的广告状态管理问题。
乐高投放平台广告状态维护的复杂程度和平台接入的广告产品数量有直接关系,当平台只接入一套广告产品的时候,有限状态机(FSM)的维护就非常简单,通过一个简单的异步任务,一段简单的逻辑判断就能很好的胜任这项工作。但是,随着平台越做越大,接入的广告产品越来越多,乐高投放平台目前已经完成接入了几十个产品类型,这些产品涉及到了黄页、招聘、房产、二手车等不同的业务线,广告的计费模式也包括CPT(按时长收费模式),CPC(按点击收费模式),CPA(按效果付费),CPM(千次展示收费)等多种计费模式,想要维护好如此庞大平台的广告状态的流转,这个问题就变得非常复杂了。下面将详细介绍乐高投放平台基于有限状态机(FSM)的广告状态管理的方案及实现。乐高投放平台广告状态维护模块的前身是一个简单的异步处理任务,随着系统的发展,接入的业务越来越多,该异步任务的逻辑变得越来越复杂,实现逻辑采取了大量的if,else/switch判断,该任务会订阅各种类型的消息流水,不同的消息内容会对平台广告状态流转产生不同的影响,该任务处理逻辑既包含一些通用的处理逻辑,也包含了一些个性化的处理逻辑,随着接入业务越来越多,这一部分系统设计的矛盾越来越突出,主要表现为下面几点:逻辑复杂:维护了几十种推广产品,监听5种类型的消息流水,大段的逻辑判断耦合严重:没有有效的隔离机制,不同推广产品的维护逻辑相互影响不易于维护:容易出现修改A产品的逻辑,影响了B产品的状态流转,给开发维护带来了极大的管理成本。为了更好的解决系统存在的问题,首先需要从整体上看清目前系统的现状,通过梳理业务逻辑,整理出目前广告系统的状态流转图,如下所示(简化版本):该方案通过策略模式+工厂模式,从产品维度做拆解,避免不同产品的相互耦合。下面详细介绍一下该方案:
消息监听模块会监听不同触发条件的消息流水,根据消息流水从查询服务获取与之对应的推广信息列表,遍历推广列表,根据推广品产id从策略工厂类获取到与之对应的策略实现类,调用策略实现类完成消息流水的业务逻辑处理。该方案的难点在于策略实现类的拆分,拆分过细会导致策略实现类过多,诸多通用逻辑无法实现有效的复用;拆分过粗会导致单个策略类承担过多的职责,耦合的问题没有彻底解决。2、 特殊的逻辑按照业务线,产品类型拆分特殊的策略实现类主要分为几大类:通用策略实现类,置顶策略实现类,招聘精选策略实现类,房产精选策略实现类,优先策略实现类等。后续接入新的推广产品处理逻辑如果能够使用现有的策略实现类则只需要配置工厂类即可实现,如果现有策略实现类不能满足需求,则新增策略实现类并且配置工厂类即可实现。1、一定程度的实现了业务逻辑隔离,通用策略处理类不修改不会影响大面积的产品推广,个性化策略实现类的修改只影响特定的推广产品。2、维护成本有所降低,升级改造只需要关心本策略类相关的推广产品,无需关心所有的推广产品。代码复用性不足,新增推广产品复用原有策略类的可行性低,因为每个推广产品总有细微的差别,但是想要复用现有的策略实现类必须要保证规则的完全一致。按照方案一的策略模式+工厂模式,一定程度上解决了系统原有的问题,但是随着平台发展越发壮大,系统逻辑越发复杂,接入产品越来越多,该模式也存在一些不足之处,策略类配置的越来越多,通用逻辑没有得到有效的复用。
经过对业务逻辑的深入分析,可以把广告状态流转图转化为通过下表来表示: 触发流水 | 校验规则 | 推广产品 | 广告状态转化 |
流水1 | 校验规则a | 推广产品100 | 广告开启 |
流水2 | 校验规则b | 推广产品101 | 广告结束 |
流水3 | 校验规则c | 推广产品100 | 广告暂停 |
流水…. | 校验规则…… | 推广产品…… | 广告….. |
最终期望通过对表中四大部分的自由组合,配置化来实现对广告状态的管理。该方案将广告流转过程拆分成了5大组成部分,由处理中心统一调配,通过配置中心实现了消息触发,逻辑校验,操作处理,推广产品四个模块规则自由组合,配置化管理的目标,下面对各模块详细介绍:触发中心负责监听各种类型的消息流水,根据消息流水获取与之对应的推广列表,推送到处理中心进行处理。消息流水主要配置如下:处理中心负责处理触发中心推送过来的消息流水和与之对应的推广列表。3、根据配置中心的配置和校验中心的校验结果调用操作中心执行对应的操作动作。将目前使用到的校验规则拆分到最小单位,拆分为各个功能点,例如:拆分到最细粒度的校验逻辑可以实现和不同推广产品的自由组合,达到配置化管理的目的。通过校验中心某些校验逻辑之后会执行相应的操作以达到修改推广状态的目的,操作中心的操作相对稳定明确,主要包括如下操作:配置中心的目标是把触发中心,校验中心,操作中心,产品id实现自由组合。100=OP01_DP01,OP02_DO01,OP03_DO02回顾一下之前系统存在的几个问题以及对应的解决情况如下:逻辑复杂的问题:校验中心每一个独立的校验规则简单独立,不互相影响,该方案把原本整体负责的问题拆分成一个一个简单的校验规则来进行维护,大大降低了系统的复杂度。耦合严重的问题:不同的校验逻辑相互独立,不同的产品,不同的触发条件通过配置文件的方式产生联系,又相互独立。扩展性差的问题:接入新产品可以最大程度的复用现有的平台能力,平台能力升级也变得简单高效。此方案通过把推广状态的流转过程分析,拆解成了触发中心,处理中心,校验中心,操作中心,配置中心五部分,实现了整个状态机的配置化管理。相比于策略模式+工厂模式的实现方式,该方案更进一步,把整个广告流转过程拆解,细化为5个组成部分,实现了配置化管理的目标,对于推广产品众多,业务逻辑复杂的平台来说,是更加有效的管理手段。
| 方案一 | 方案二 |
逻辑复杂的问题 | 解决 | 解决 |
耦合严重的问题 | 基本解决 | 解决 |
扩展性的问题 | 基本解决 | 解决 |
不易于维护的问题 | 基本解决 | 解决 |
结合业务现状,对比两个方案的优缺点,发现随着业务的发展,平台接入广告产品的种类越来越多,方案二能够更加有效的解决上述问题,最终选择方案二作为乐高投放平台广告状态维护的实现方案。除了上述的两种方案,常见的状态机实现方案还有以下几种:HFSM:分层有限状态机,多于解决状态特别多,使用FSM维护困难的问题。Behavir Tree:行为树实现,多用于解决各个状态相互关联,相互影响的场景。Akka FSM:该方案较系统的解决了有限状态机常见的9类问题,但是对于“如何处理某个状态下收到的事件,并转换到下一个状态“这一问题的解决并不彻底。投放平台遇到的状态管理问题,矛盾点主要在于状态流转规则的复杂,而不在于状态多,或者状态之间的关联关系复杂,投放平台最终采用的方案二更能贴合我们的业务场景,解决了我们状态流转规则复杂的问题。广告状态的维护是做广告业务绕不开的问题,从系统/平台发展的角度来看,广告状态维护的设计实现可以分为三个阶段。第一阶段:系统建立之初,系统逻辑简单,为了低成本快速上线的目标,可以采取简单粗暴的if,else/switch判断的方式来实现。第二阶段:系统发展到一定程度,逻辑规则变得复杂,原有的设计方案无法很好的服务系统的发展,系统架构设计可以升级为策略工厂模式来管理广告状态的流转。第三阶段:系统发展到了平台阶段,平台管理的多种类,海量广告,业务逻辑非常复杂,原有的设计模式下,系统维护困难,问题频发,平台进而升级为配置化管理方式。对于不同量级的系统/平台来说,广告状态的管理在不同阶段有不同的解决问题的思路,做系统设计,解决系统问题,没有最好的方案只有最适合自己系统的方案。以上分享的是乐高投放平台基于有限状态机(FSM)的广告状态管理的实现方案及实现,分享出来供大家参考。阅读推荐
一招提速30ms,解密58同镇推荐业务之动态日志级别配置实践
深度|万字长文:如何从 0 到 1 构建个性化推荐?
58招聘推荐排序算法实战与探索