咱们最早落地的业务是在用户增加上,闲鱼的用户增加业务有以下描述:算法
在年初时,咱们在用户增加下作了多个实验,其中两个实验以下:编程
之因此会作以上实验,主要仍是但愿用户能在APP上多停留一会。当用户浏览时间越长,就越有可能发现闲鱼上还有不少有趣的内容,不管是商品宝贝仍是鱼塘内的帖子。从而达到吸引用户下一次还能再回来的目的,最终带来用户增加。咱们作的实验上线后大部分都取得了不错的业务效果,可是在过程当中也暴露了两个问题:安全
针对上述问题,咱们先作了一层业务抽象。运营先经过对用户的各类行为进行一个分析和归类,得出一个共同的具体的规则,再将这个规则实时地做用到用户身上进行干预。网络
针对这层业务抽象,咱们再作了工程化,目的就是为了提高研发效率和运营效率。这样就有了第一个方案——基于事件流的规则引擎,咱们认为用户的行为是一串顺序的行为事件流,使用一段简单的事件描述DSL,再结合输入和输出的定义,就能够完整地定义一个规则。架构
以上述用户增加的第二个实验为例,以下图所示的DSL便可简单表达出来:编程语言
该规则引擎能够很好地解决以前用户增加业务下的几个策略,随后咱们进行了内部推广,准备在闲鱼C2C安全业务下也落地。在C2C安全业务上有以下描述:工具
在C2C安全业务上,也有一个看似是一个针对一系列行为做出的规则抽象,以下图所示:性能
可是将上述规则套上规则引擎后,就会发现没法将安全的规则套上规则引擎。假设咱们的详细规则是1分钟内被拉黑2次,就对该用户打上高危标记。那么咱们想想,当来了第一个拉黑事件后,匹配上了。而后紧接着来了第二个拉黑事件,也匹配上了。此时按照规则引擎的视角,条件已经知足了,能够进行下一步操做了。可是再仔细看一看规则,咱们的规则是要被不一样的用户拉黑,由于有多是同一个用户操做了屡次拉黑(同时多开设备)。而规则引擎上只知道匹配到了2次拉黑事件,对规则引擎来讲已经知足了。却没法知道是不是不一样人操做的。起根本缘由是由于在规则引擎里,事件都是无状态的,没法回溯去作聚合计算。优化
针对规则引擎的局限性,从新分析和梳理了咱们的实际业务场景。并结合了业界知名的通用的解决方案后,设计出了新的方案,定义了新的DSL。能够看到,咱们的语法是类SQL的,主要有如下几个考虑:spa
新的DSL方案与以前的规则引擎相比主要有如下几个加强:
针对以前的C2C业务上的规则描述问题,使用新方案的例子以下:
基于这套用EPL(Event Programming Language)写出的DSL,为了作好工程化,咱们作了以下的总体分层架构。为了快速实现最小闭环验证效果,咱们选择先基于Blink(Blink是阿里对Flink的内部优化和升级)作云上的解析和计算引擎。
在这个分层架构里,至上而下分别是:
经过切面的方式拦截全部的网络请求和行为打点,再记录到服务端日志流里。同时经过一个事实任务对事件流进行清洗,按前面定义的格式清洗出咱们想要的事件。再将清洗后的日志输出到另外一个日志流里,供EPL引擎来读取。
因为咱们采起了类SQL语法,而Calcite是业界通用的解析SQL的工具,所以咱们采用Calcite并经过自定义其中的parser来解析。若是是单一事件的DSL,则会解析成Flink SQL。若是是多事件的DSL,则会解析后经过直接调用Blink的API接口的方式来实现。
当EPL引擎计算出结果以后,会输出给用户触达模块。首先会进行一个Action路由,最终决策出须要由具体哪个Action来响应,最后经过与客户端之间的长链接将Action下发到端上。端上收到具体的Action后,会先判断当前用户的行为是否容许展现该Action。若是能够的话,就直接执行Action的具体内容,曝光给用户。用户看到此次响应后会有相应的行为,那么这部分的行为会影响到Action路由,对此次的路由的作出一个反馈。
新方案上线后,咱们就在愈来愈多的业务场景里进行了落地。这里列举2个例子:
在上述鱼塘的例子里,能够看出来,咱们这套方案已经有了一点算法推荐的影子了。在上述租房的例子里,因为规则过于复杂,用DSL表达起来很麻烦,因此就作成只采集4次浏览不一样租房宝贝的规则,即触发后,就将这里的数据都给到租房的具体开发的业务方,这也是咱们在落地过程当中摸到的边界。
使用这一套完整方案,研发效率上有了很大的提高。原先经过写代码case by case的方式通常要4个工做日完成整个研发流程,极端状况下须要跟客户端版本则须要2-3周的时间。如今经过写SQL的方式通常要0.5个工做日便可上线。此外,这套方案还有以下几个优点:
经过在多个业务的落地实践,咱们也摸索出来这套方案的适用边界:
当前整套方案还有以下几个问题:
所以综上,咱们将来的规划将会聚焦于端侧实时计算能力的挖掘和算法能力的结合上。
本文做者:闲鱼技术-兰昊
本文为云栖社区原创内容,未经容许不得转载。