HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

规则引擎:大厂营销系统资格设计全解

  • 2020-04-26
  • 本文字数:3454 字

    阅读完需:约 11 分钟

规则引擎:大厂营销系统资格设计全解

业务进行营销活动目的是用最少的钱实现更好的营销效果,此时就需要针对营销活动的资格进行控制,其中就包括了用户身份、用户所处的环境等等一系列因素的考虑,且为了防止恶意套取营销费用和做到营销效果的持续性,会进行活动相关次数的控制。此时为了适应业务不断变革的营销活动资格,好的资格设计就非常重要。


营销活动业务在配置中会同一时间存在多个营销活动,用户进入某个场景,首先需要给用户展示目前用户能够享受的营销活动,增加用户参与此场景的意向,然后用户参与场景后需要给用户提示对应的营销活动,用户如果没有参与成功需要给用户提示具体没有参与成功的原因。那么在参与前,具体的场景中需要进行用户资格的校验,并且用户参与后需要进行资格记录。


同时,资格校验能够有效防止用户重复参与的问题,通过配置用户的次数资格来进行校验,用户参与成功一次进行记录,后面用户参与前对次数资格进行相关的校验。



资格分类


资格设计先要针对资格进行分类,通过不同的分类进行各自分类领域模块设计。分类的原则是分层漏斗分类:优先过滤大量不满足、消耗服务器资源较少的活动,再过滤需要消耗服务器资源较多的活动,最后是进行风控资格校验。按照这个分类原则后面可能会出现多个营销活动,这个是另外一个话题—营销推荐设计。



以上是目前苏宁金融这边针对资格设计的分类:静态资格、动态资格和风控资格。此处风控资格校验作为独立的一个分类并且放在最后,主要是由两个方面考虑:(1)风控的内容很多,在苏宁金融有专门的风控中心来进行风控规则的制定和执行;(2)风控返回的风控级别也有很多,营销活动的不同、触发风控的级别不同,对应的营销活动处理逻辑也不一样。


下面针对以上的分类的静态资格和动态资格进行相关的领域模块具体设计探讨。


静态资格


静态资格在苏宁金融营销中的定义是:用户进入具体场景、当时用户属性标签的一个静态数据。


静态数据的获取方面主要通过两个部分获取:(1)上游系统的传递,这个数据主要是获取用户所处的场景数据,包括但不限于:用户当前进行的业务及业务数据、用户使用终端、网络环境等等数据。(2)用户属性标签的大数据获取。在苏宁金融大数据中心有一套完整的用户实时标签库,用户请求后通过次标签库实时查询用户目前的标签。


静态数据的过滤在技术方案中适合采用规则引擎进行相关资格校验。目前在苏宁金融的营销系统中使用 Drools,主要是考虑以下几个方面:


(1) 业务规则较多,如果使用编码方式新增规则就需要进行相关的编码,增加代码量和维护成本。


(2) Drools 的自定义关系操作符:通过自定义关系操作符可以针对不同的业务规则配置需要的操作符还可以针对每个活动不能匹配的原因进行内部埋点记录,方便运营进行客诉查询。


(3) 纯 java 实现,学习成本低。


业务配置生成 drl 文件设计


关于生成 drl 文件的设计,先来看看 drools 引擎原理:


Drools 引擎通过每个条件进行匹配,最终匹配出相关的活动,所以在设计中需要考虑最终返回的数据是活动集合。


Drl 文件组成:



通过原理及文件组成,设计 Drl 文件生成的类图如下:



writeRuleFile 是入口,通过入口进行内部方法组装,此方法需要功能是组装文件内容和写文件;writeDrlHead 方法为写文件头部包、引用和全局变量定义;assembleEvaluatorDefinition 方法是组装自定义操作符规则;getActRuleWhenCondition 此方法为拼接规则字符串;writeActivityRule 此方法为活动的规则写入。


以上是一种纯 java 代码实现 Drl 文件生成的一个方式,目的是为了让大家能够理解 Drl 文件的结构。实际操作过程中也可以通过 freemarker 模版来生成对应的 Drl 文件。


Drools 规则加载


此处规则加载设计可以设计为内置定时器扫描规则生成表是否有新增记录或者采用分布式集群通知的方式进行加载。




目前,苏宁内部的统一配置平台采用的是自研的 SCM 平台,能够很好地支持实时修改,应用服务器集群每台应用监听具体某个配置文件的内容变更。


应用服务器监听到需要进行 Drl 文件 加载后,通过拉取 Drl 文件,并读取其中的内容生成对应的 KieBase。


静态资格匹配


为了更加通用性在设计中可以设置规则匹配的入参为 Map 形式,在进行匹配前需要把静态资格数据转化为 Map 数据格式,然后在生成的 KieBase 中获取 KieSession,通过此 KieSession 进行规则匹配。


KieSession 需要设置全局的一个集合,来返回匹配到相关活动编码数据,同时需要考虑活动是有状态和有效期的,所以在拿到静态数据匹配的活动编码后,需要对活动的状态进行筛选,拿到的是生效且在有效期范围内的活动。


动态资格


此处动态资格主要是指活动的次数和用户次数。营销活动为了能够使更多的用户能够参与,防止某些用户的重复参与,会对用户的每日、每月、总参与次数进行限制,同时活动的经费是有限的,为了能够使营销活动效果做的更好,也会对活动的每日、每月、总次数进行限制。


动态资格设计可以分为两个维度,一个是对象,一个是周期:



通过上图设计,周期维度确认好后变更的可能性比较小,可以在前期调研阶段确认好周期范围。不过,对象变更相比较周期而言会更频繁,前期系统上线的时候确认一个自然人可能只有帐号、绑定手机两个属性,后期通过系统的不断迭代及技术的不断进步这个属性可能会进行扩容。所以,在进行架构设计的时候需要考虑具体对象的扩展性。同时,为了高并发的查询、次数的扣减或者回滚,可以通过缓存来代替数据库的记录和操作,当然为了保证数据的可恢复性,可以设计实时缓存,异步落库的操作。


动态资格组装


资格组装按照分析,采用抽象类封装内部实现,每个对象通过继承抽象类,实现具体的抽象方法的方式来实现。



抽象类 AbstractDimensionDynamic 中有两个抽象方法获取对象 targetType 和获取对象值 targetValue 是在具体类中进行实现。dynamicAssemble 方法是进行 dynamicKey 的拼接并组装动态资格的具体对象,最终得到动态资格对象的集合。


AbstractDimensionDynamic 的子类是具体的动态资格对象,每增加一个对象,通过增加子类的方式来实现。


动态资格服务



此处设计中 DynamicService 对外提供的是动态资格校验和动态资格扣减两个服务,在实际过程中还会存在回退的服务,这个需要自行进行扩展。


抽象类 AbstractDynamicService 中的 dimensionDynamics 是一个 List,并且注解为 @Autowired,Spring 会自动从容器中取出 DimesionDynamic 的实现类装配到 List 类型的 dimensionDynamics 中,从而简化了依赖注入的过程,并且有新增实现类的时候系统启动会自动注入。


@Autowiredprivate List<DimensionDynamic> dimensionDynamics;
@Resourceprivate RedisService redisService;
复制代码


其中的 assembleDynamicRecordList 方法是通过遍历 dimensionDynamics,组装需要的查询或者扣减的动态数据记录;rollback 方法是扣减出现异常或者扣减超过限制后进行回滚使用的操作,此方法需要抛出异常,供上游判断是否需要进行处理。


缓存使用 Redis,主要是考虑在 redis 中的 incrBy 和 decrBy 都是原子性操作,这个在高并发的场景中防止由于并发导致的累计错误问题。而且 redis 的 mget 命令可以批量查询,主要是由于 redis 使用基于 RESP 协议的 rpc 接口,而 redis 本身的数据结构非常高效,所以 IO 和协议解析是个不容忽略的资源消耗。通过 mget 将多个 get 请求汇聚成一条命令,可以大大降低网络、rpc 协议解析的开销,从而大幅提升缓存效率。


DynamicServiceImpl 是 DynamicService 的具体实现,并且要继承 AbstractDynamicService 抽象类。需要实现 dynamicChack 动态资格校验和 dynamicDeduction 动态资格扣减方法。


动态资格校验是通过组装的动态记录数据集,到缓存中查询目前存储的值跟对应动态资格最大值进行比较,当缓存值大于等于最大值表示动态资格校验不通过。


动态资格扣减使用缓存的 incrBy 进行累加,这块需要针对每个累加后进行判断来减少跟缓存的交互,并且需要把已经累加的数据进行记录,提供回滚资格使用。


以上是针对营销系统的资格设计的一个设计思路和相关实践的简单案例,在具体设计中需要考虑的问题比案例中的更加复杂。比如:用户资格不满足原因的输出、异步动态资格数据入库处理、动态资格校验返回所有不满足原因等等。这些就需要进行相关的扩展和针对目前公司的基础配套设施的情况进行选择设计。


作者介绍 :


王海民,苏宁金融研发中心高级技术经理,主要负责苏宁金融会员及互联网研发中心的营销部门工作。具有营销、电商、支付、金融等相关领域 10 年以上工作经历;擅长互联网产品服务端应用技术架构。


本文转载自技术琐话公众号。


原文链接:https://mp.weixin.qq.com/s/TiSEYDdODiuVyBOWpOMzRA


2020-04-26 13:223897

评论

发布
暂无评论
发现更多内容

EPBC环保生态链系统开发案例丨环保生态链EPBC源码平台

系统开发咨询1357O98O718

环保链APP系统开发案例

新思科技最新报告显示开源安全是首要考虑因素

InfoQ_434670063458

区块链信息共享应用落地搭建解决方案

t13823115967

区块链+ 区块链应用 信息共享

某美女的程序员老公半夜都还不回家,原来是偷偷在公司看Redis+JVM+Spring cloud+MySQL技术文档

Java架构之路

Java 程序员 架构 面试 编程语言

滴滴开源小桔棱镜:一款专注移动端操作行为的利器

滴滴技术

开源 滴滴 移动端

DeFi流动性挖矿系统开发(案例源码开发)

系统开发咨询1357O98O718

defi流动性挖矿系统开发

超详细讲解!Android面试真题解析火爆全网,搞懂这些直接来阿里入职

欢喜学安卓

android 编程 程序员 面试 移动开发

Mybatis动态映射,so easy啦

田维常

四面腾讯pcg后端开发岗,一个星期面完成功拿到20K的offer。分享面经

Java架构之路

Java 程序员 架构 面试 编程语言

仅凭这份Java大纲笔记,我如愿拿到了阿里offer。

Java架构之路

Java 程序员 架构 面试 编程语言

阿里架构师经验分享!啃完999页Android面试高频宝典,面试心得体会

欢喜学安卓

android 程序员 面试 移动开发

区块链BaaS应用平台开发

13828808769

iOS面试基础知识 (一)

iOSer

ios 面试 runtime 编程开发 iOS Developer

还有谁比阿里人更懂SpringCloud Alibaba 呢?P8大牛纯手打笔记免费分享!

Java架构之路

Java 程序员 架构 面试 编程语言

DeFi借贷质押系统APP开发|DeFi借贷质押软件开发

系统开发

Github 2020 年度报告:你以为新冠击溃了开发者?不!他们创造了更多代码...

阿里巴巴云原生

开源 Serverless 程序员 代码

Scala中String和Int隐式转换的问题分析

木子李G

scala 大数据 编程 隐式转换

SGY奇点交易所系统软件开发|SGY奇点交易所APP开发

系统开发

刚入职,就被各种 Code Review,真的有必要吗?

xcbeyond

方法论 研发管理 编程习惯

挖矿矿池系统开发详情丨挖矿矿池源码案例

系统开发咨询1357O98O718

挖矿矿池系统开发案例 旷工系统开发功能

四币连发平台系统开发详解丨四币连发源码(案例)

系统开发咨询1357O98O718

四币连发系统开发案例详解

架构师训练营第三周作业

Geek_xq

智慧警务开发,二维码定位报警系统搭建

t13823115967

智慧公安 智慧公安扫码

区分Protobuf 3中缺失值和默认值

Gopher指北

protobuf Go 语言

《数据结构与抽象:Java语言描述》.pdf

田维常

数据结构

服务于阿里、滴滴、华为等一线互联网公司的分布式消息中间件RocketMQ核心笔记

Java架构追梦

Java 架构 面试 RocketMQ 消息中间件

架构师训练营第八周作业

李日盛

算法

DeFi流动性挖矿系统开发详解方案

系统开发咨询1357O98O718

defi流动性挖矿系统开发

用60行代码实现一个高性能的圣诞抽抽乐H5小游戏(含源码)

徐小夕

Java 大前端 H5游戏 H5

20分钟带你掌握JavaScript Promise和 Async/Await

葡萄城技术团队

Java

恕我直言!有了这份MySQL学习文档,你收藏夹里的其他MySQL学习资料都可以扔了

Java架构之路

Java 程序员 架构 面试 编程语言

规则引擎:大厂营销系统资格设计全解_语言 & 开发_技术琐话_InfoQ精选文章