一站式运营营销平台
前言
营销增长在当下是一个很热门的词语,当公司核心业务做到一定规模后,都会开始进行增长拉新、留存运营、流量运营等一系列运营手段来促进营收,当然各个业务部门由于自身 KPI 的不同、以及经费的不一致,也会有多种不同的营销策略和打法。而营销增长(这个我暂且称为笼统的词语),就诞生在了这个趋势上,各个公司因此也成立相应的部门去做营销增长方向的技术支持。
由于之前曾在某头部打车公司从事过相关领域,并看到有相关同学公开了该系统,并做了相关直播分享,特想结合自己实际和理解,对营销平台的设计架构和技术方案做一个分享,尽量针对该同学讲到的范围内的知识点进行文字补充,若读者有兴趣,可以后续针对固定点进行展开。
背景
针对在 APP 端某一个相同的用户行为,多个业务部门需要有不同的转换方式。比如,我们要在打车的时候,给用户发放优惠券,在支付完成的时候,要给用户发券或者发放权益,以及做一些千人千面的场景。
在这些业务需求来的时候,我们同大多数人一样,刚开始来个需求做一个需求,然后自定义的需求多了的时候,会发现某一相同的用户行为,需要写多个 if else 来进行业务侧的适配,并且随着业务要求的千奇百怪,这套系统运维理解成本也成指数增加,最终到了一个改不动的地步,没办法,那就重构吧。
当一件事做的复杂的时候,我们需要回过头来看下,是不是源头就是错的,因此,我们开始对此进行抽象,我们开始抽象用户的行为,app 的行为,触发的时间,条件的过滤等,于是,一套 TCA 体系就这么诞生了,并基于这套框架,进行后续一步步的散枝开花。
业务模型及总体架构
当设计这套系统的时候,我们需要明确四件事:定位、目标、内容、边界。
关于定位,我们最开始知道的是我们要做的是营销系统。
关于目标,是帮助运营同学可以便捷灵活制定一系列营销策略组合,提升整体的用户规模,从而提升单量和 GMV,促进业务持续增长。
关于内容,我们需要解决的实际业务问题,比如花式发券、花式触达、天降红包、弹窗、预估等面向用户带有营销属性的一系列运营行为。
关于边界,区分与其他业务的边界,哪些是属于我们该做的。这些就因不同公司的规模大小、业务划分都各有不同。
当系统这四大要素确定好后,我们就开始进行业务模型的抽象。
我们首先对用户行为进行解耦,分析单一的面向用户的营销行为,将其抽象为三个部分:触发事件、过滤条件、营销行为,我们简称这为 TCA。如下图所示:
TCA 是整套系统的精髓设计点。这个架构成立后,比如我们要在某个特定时间给用户发送短信,发送完短信后,再发一张券,我们可以抽象成两个 TCA 活动单元,并进行串行配置,这样,当执行完第一个活动后,下次进来我们直接去执行第二个活动,组合的方式,这样就能直接满足运营侧的需求。
整体架构如下:
我们确定一个单一的 TCA 后,我们开始对其进行进一步的架构扩充,分为五个层面:
配置层 :活动配置和存储
特征层 :规则解析所需的特征服务
行为层 :权益和消息发送
Engine:Step 流转和规则解析
接入层 :各事件转换与接入
核心模块
活动编排
编排顾名思义就是一套运营配置后台系统,主要是提供给运营进行营销活动的配置。这块唯一特别可以讲到的是,我们通过一块画布的形式,然后提供给运营,运营在这块画布上,通过我们提供的已有营销素材和组件进行自我绘画。然后产生一个个当下的营销活动,编排完成营销活动后,即可进行相关审核上线。
整个编排后的活动,我们将构建成一棵二叉树的机制,从左到右进行匹配,匹配到的 action 然后为当下需要执行的 action。
触发事件
用户行为的触发事件,这些触发事件,我们可以用某些特定标识符进行标记,与前端形成一组约定,每次传递时,可以根据该字段进行初步匹配。
定时事件
定时需要执行的事件,这种情况,可以用分钟级别的定时任务进行特定处理,针对于大人群的活动,进行提前下载切片,关于这点,可以参考我之前写的定时器文章,大同小异,大家可以根据自身公司情况去寻找符合自身的需求。
执行引擎
引擎这块,主要用于活动的过滤,筛选出最终命中所需要执行的活动,大体架构图如下:
首先,我们会将所有活动编排缓存在内存中,构建多个符合场景筛选的数据结构和索引去匹配每一次请求。我们引擎的入口可以是 api 和 mq 两种形式,触发者可以是前端、业务方、以及定时任务等,通过 api 和 mq 两种方式进行引擎的每一次运行。
当请求过来时,先进行 trigger 过滤,筛选出符合触发条件的活动,当匹配到符合条件的活动后,我们根据优先级,然后一一进行活动内匹配,通过二叉树遍历的机制,去匹配到当前请求是否能走到该触发节点的执行动作,若走不到就下一个活动,否则就停下执行当前具体 action。
关于这块,我们会遇到很多条件过滤的场景,如上所述,每个 tca 都有不同的 c,我们需要去过滤掉这些不符合条件的动作,这个时候,我们采用到了规则引擎来判断不断增加的过滤条件,减少 if else 的编写。另外,我们也将规则引擎做了一层配置化,利用内部 Apollo 配置平台,将一些规则存储在配置中心进行读取,这样当新增规则时,只需要配置相关 dsl 语句即可,无需代码编写。
同时,我们要确保当前命中到只有一个活动下的一个动作行为,当然这块可以根据业务方的诉求去进行合理的拆解,比如,我可以命中一个 tca,也可以命中一串 tca。
当确定好要执行的 action 后,我们整理当前执行的 action 集合,并将其作为参数调用后续的 ap 项目,来进行动作的具体执行。
执行动作
ap 我们可以理解为用户命中活动后,所需要执行的一系列营销行为,该过程不依赖于 db,却依赖于各个下游系统,并通过 redis key 来保障执行的幂等和顺序性。
我们在接收到上游传递过来的参数后,我们根据策略进行一波 action 的整理,得到排序后的 action,然后具体去执行这一套 action 营销行为。
我们根据 action_list 依次去执行调用下游,当遇到标记为异步的 action,我们直接无需要等返回,直接协程执行,当遇到同步的需要等待最终返回结果,若返回失败,则停留到当下,并将结果返回。
核心入口伪代码如下:
每个 action 都会实现 execute 这个接口,后续新增 action,只需要两步骤:
接口实现;
加入 switch 可执行对象当中。
一条 action 的执行,会根据 step 和 action index 产生一条唯一的执行 key,同时结束后会产生一个 mq,用于其他业务方的对接,以及自身后续的数据特征沉淀。
当然我们为什么要这么拆分?
原因个人理解最为简单的点,我们将 action 收集成一个素材库,每个 action 有自己独特的标识,然后每次新增的 action,只需要添加 action 对应接口的相关实现即可,若想废弃,也只需要删除指定的文件即可,这样可以保证整个项目的可读性和可维护性,而不用随着项目扩大,而迷失在各处环节的 if else 中,最终陷入到了无法改动的地步。代码一定冗余度,是后续可伸缩的关键点。
特征管理
当命中执行后,可以收集用户参与的营销活动信息,并沉淀抽象相关用户行为特征,提供统一的特征数据获取服务,这块相当于后续自给自足。
数据特征管理,主要用于前面引擎当中的一些 condition 的匹配,我们针对不同业务方千奇百怪的匹配过滤条件需求,通过数据特征的沉淀,产生一些列数据特征,然后不同过滤条件对应不同特征,从而只需要匹配到当前特征即可满足过滤条件,化简了较为复杂的过滤条件运算,减少了从不同业务方去调用接口获取相关匹配信息。
后言
文章暂且写在这,当读者有兴趣尝试去实现的时候,会发现整个系统内部还有很多细节可以深挖,以及流量增大时的处理、mq 积压、action 重试机制、engine 过滤规则、索引构建等问题,都可以后续一步步讨论,每个细节其实都有较为深刻的思考点以及优化方向。
若有兴趣的可以再去看下滴滴分享的 pope 系统直播课,本文抛砖引玉,并不涉及其核心代码。
没有最完美的架构,只有更适合当下业务场景的方案。
在工作中思考,在思考中沉淀,慢慢生活。
版权声明: 本文为 InfoQ 作者【Quincy】的原创文章。
原文链接:【http://xie.infoq.cn/article/970f28ff0fb4020c56a173838】。文章转载请联系作者。
评论