写点什么

一站式运营营销平台

作者:Quincy
  • 2023-09-26
    湖南
  • 本文字数:3529 字

    阅读完需:约 12 分钟

一站式运营营销平台

前言

营销增长在当下是一个很热门的词语,当公司核心业务做到一定规模后,都会开始进行增长拉新、留存运营、流量运营等一系列运营手段来促进营收,当然各个业务部门由于自身 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,我们直接无需要等返回,直接协程执行,当遇到同步的需要等待最终返回结果,若返回失败,则停留到当下,并将结果返回。

核心入口伪代码如下:

func (h *handler) Entry(ctx context.Context, params *params.ActionEntry) (interface{}, int, error) {	// 1、策略过滤  	// 2、选择具体执行	for _, action := range params.ActionList {		actionKey := fmt.Sprintf("ap_step_%d_action_%d", action.Step, action.ActionIndex)		executor := switchActionExecutor(action.ActionType)		if executor == nil {			continue		}		// 记录当前executor		res, errNo, err := executor.Execute(ctx, action.Params)		if err == nil && errNo == code.Suc {			actionRes[actionKey] = res		}		if err != nil {			actionFailRes[actionKey] = err.Error()		}	}	// 结果汇总
// mq产生 return nil, code.Suc, nil}
复制代码

每个 action 都会实现 execute 这个接口,后续新增 action,只需要两步骤:

  1. 接口实现;

  2. 加入 switch 可执行对象当中。

一条 action 的执行,会根据 step 和 action index 产生一条唯一的执行 key,同时结束后会产生一个 mq,用于其他业务方的对接,以及自身后续的数据特征沉淀。

当然我们为什么要这么拆分?

原因个人理解最为简单的点,我们将 action 收集成一个素材库,每个 action 有自己独特的标识,然后每次新增的 action,只需要添加 action 对应接口的相关实现即可,若想废弃,也只需要删除指定的文件即可,这样可以保证整个项目的可读性和可维护性,而不用随着项目扩大,而迷失在各处环节的 if else 中,最终陷入到了无法改动的地步。代码一定冗余度,是后续可伸缩的关键点。

特征管理

当命中执行后,可以收集用户参与的营销活动信息,并沉淀抽象相关用户行为特征,提供统一的特征数据获取服务,这块相当于后续自给自足。


数据特征管理,主要用于前面引擎当中的一些 condition 的匹配,我们针对不同业务方千奇百怪的匹配过滤条件需求,通过数据特征的沉淀,产生一些列数据特征,然后不同过滤条件对应不同特征,从而只需要匹配到当前特征即可满足过滤条件,化简了较为复杂的过滤条件运算,减少了从不同业务方去调用接口获取相关匹配信息。

后言

文章暂且写在这,当读者有兴趣尝试去实现的时候,会发现整个系统内部还有很多细节可以深挖,以及流量增大时的处理、mq 积压、action 重试机制、engine 过滤规则、索引构建等问题,都可以后续一步步讨论,每个细节其实都有较为深刻的思考点以及优化方向。

若有兴趣的可以再去看下滴滴分享的 pope 系统直播课,本文抛砖引玉,并不涉及其核心代码。


没有最完美的架构,只有更适合当下业务场景的方案。

在工作中思考,在思考中沉淀,慢慢生活。

发布于: 2023-09-26阅读数: 24
用户头像

Quincy

关注

路过岁月,慢慢生活 2018-08-01 加入

一个心怀远方的搬砖懒汉

评论

发布
暂无评论
一站式运营营销平台_运营_Quincy_InfoQ写作社区