|
作者 | 贴吧UEG技术组introduction本文首先介绍了规则引擎的使用场景,引出贴吧规则引擎。从组件、变量、规则、处置四个模块介绍了规则引擎的组成部分,同时对最终规则文件的编译过程做了详细介绍。为了做到低代码,在规则配置上做到平台化,非研发同学即可完成。增加新的变量也只需要在变量平台进行简单操作,无需额外的代码提交。另外框架层面支持并行和异步的封装,在服务调用上也尽量做到减少代码,提高研发同学的效率。最后文章对贴吧规则引擎做了总结,也提供了一些常见的使用场景和思路。全文6951字,预计阅读时间18分钟。GEEK TALK01背景百度贴吧是一个拥有10多年历史的UGC产品,在业务迭代中难免会有很多业务逻辑的代码,其中一部分业务逻辑用if-else等硬编码的形式开发,一部分引入了配置文件,通过配置文件的规则去执行不同的业务逻辑。在某些运营活动或权益规则中,需要频繁增加或者更改一些规则,这部分规则经常变动的部分就需要规则引擎来统一管理。规则引擎是一种专注于业务规则的服务,它可以将业务规则从代码中剥离出来,使用预先定义好的语义规范来实现这些剥离出来的业务规则。规则引擎通过接受输入的数据,进行业务规则的评估,并做出业务决策。因为规则引擎将复杂的业务逻辑从业务代码中剥离出来,所以可以显著降低业务逻辑实现难度;同时,剥离的业务规则使用规则引擎实现,这样可以使多变的业务规则变的可维护,配合规则引擎提供的良好的业务规则设计器,不用编码就可以快速实现复杂的业务规则,同样,即使是完全不懂编程的运营或者产品人员,也可以使用图形化的界面来自定义规则,实现代码一样的效果。下面对一些需要使用规则引擎的场景进行举例:1、单规则迭代用户标签->包含A关键词->权益A用户标签->包含A关键词->权益A? ? ? ? ? ? ? ?->包含B关键词->权益B用户标签->身份豁免策略/机器账号->包含A关键词->权益A? ? ? ? ? ? ? ?->包含B关键词->权益B用户标签->A模型结果大于1 ->豁C类用户->包含A关键词->权益C可见随着业务的发展,需要不断的调整权益规则,这部分如果硬编码写死在代码中,需要频繁上线,增加了工作量,并且随着业务逻辑的增多,后期维护成本增高。2、持续接入新的能力除了目前的字符串比较能力,一般的规则引擎还会接入各种各样的模型能力,一般通过RPC的形式请求不同的服务,随着接入的服务越来越多,可以组合的规则也是成倍的增长;比如新接入图片模型识别后,所有图片识别的结果会过其他相关的模型,相关的模型调用逻辑就增加了一倍;又如接入了某些模型,要根据模型的分数做相应的处理调整,需要频繁的改动分值对应的处置手段,同时为了应对突发的场景,也需要频繁的更改规则。这些操作如果没有一个自动化的规则引擎,就需要把大量的规则逻辑写在代码里,经过长时间的迭代,规则变得非常臃肿,无论对后续的开发还是定位问题的效率都会带来问题。GEEK TALK02贴吧规则引擎组成部分贴吧规则引擎要做到规则灵活可配,无需研发介入,就需要尽可能的把包含判断逻辑的部分全部下放到平台,通过平台的勾选对规则进行实现。上图为规则引擎整体的模块划分,主要分为四部分:组件服务:组件服务是对第三方服务的封装,比如调用图片模型服务、调用帖子属性等内容服务,一般是RPC调用;组件需要RD开发代码,但是贴吧规则引擎的组件调用不掺杂业 务逻辑,仅仅是定义一个函数function,通过函数的入参调用第三方服务返回结果;变量平台:变量又称算子,是配置规则的参数;变量分为业务调用时传的入参、使用组件返回的结果等。贴吧规则引擎通过专用平台管理变量,RD和PM均可以在平台上配置变量;规则引擎:规则引擎平台涉及到了具体每一条规则,通过图形化的界面生成规则,该平台不需要RD介入,通过平台化的操作生成具体的规则。处置方法:该处置为RD定制化开发,针对帖子、用户或其他场景的召回处置处理。一般定义一个rpc请求回调相关业务,处置方法因为是场景定制化的,所以这部分需要研发介入开发,但是处置方法更新的频率非常低,一般都是复用已有的能力。2.1?组件服务规则引擎所有配置的数据不可能都是上游参数传递,很多是通过调用第三方服务获取;比如通过帖子id获取的帖子详情数据,通过用户uid获取用户的扩展属性,这里都需要调用第三方服务;组件的开发非常简单,只需要声明一个函数,并实现其静态方法。为了后续的性能考虑,函数声明时可以指定sync(串行)、async(异步)、parallel(并行)三种执行方式,贴吧规则引擎会在调度的时候按照类型,使用更高效的方式执行对应的方法。图中给出了一个demo组件,可以看出组件是不关注业务的,可以自定义入参和返回值,具体调用函数的入口及参数也不需要额外关注,更符合lib库或者util方法的实现方式,这种组件的好处是开发简单,解耦业务逻辑,增加组件的复用性,同时也降低了研发同学的工作量。另外对于mode的工作模式,分为以下三类,具体的实现都是框架实现,组件的开发方不需要关注:sync:同步调用,使用的时候串行执行,函数间是阻塞的;async:异步调用,定义function的时候分为before、after两组方法。Before阶段为发起rpc请求,等待第三方服务回调后执行after方法,可以应对好耗时的服务接入。parallel:并行模式,属于同一层级的parallel 函数并行执行,类似于多线程或者golang的goroutine模式,目前贴吧的规则引擎采用php开发,不具备多线程的相关能力,所以这里并行是在before组装rpc参数,通过curl_multi统一发起并行请求,在after函数取到结果。以上能力在规则引擎框架上已经封装,组件的研发RD只需要关注PRC的实现即可,根据函数的定义框架实现并行或者异步的调用。2.2 变量平台变量或者算子就是规则引擎中做规则判断使用的参数,比如用户名、帖子id、用户等级、帖子内容、模型识别的结果等,这部分的内容越多,规则引擎可以创建规则的『素材』越多;变量的来源分为三个部分:(1)平台预定义的变量:比如一些常量数字或者特定字符串,这部分内容比较固定,变动较少。(2)业务入参:业务在请求规则引擎的时候可以把尽可能多的参数变量传递过来,除了帖子、用户、吧相关的数据,还可以把用户ip、ua等各种数据一并传递,这些数据在变量的平台化界面上可以做简单的筛选或者摘取,生成新的变量。如图举例:input是一个完成的业务请求的变量,取input中的title生成testTitle变量,这样就可以单独使用testTitle做一些规则上的判断。(3)组件调用:在组件的部分已经定义了具体的方法,该方法类似于lib库或者util,具体的请求的入口在变量平台实现,入参就是其他变量。如图举例:testRPC是定义的组件,其中入参是testTitle变量,返回的大结果作为一个testRPC变量。后面可以对testRPC变量做具体的拆分,比如testRPC中的data.score作为一个单独的变量,用score这个变量做后面的规则定义。整体来说,input是上游传过来的基础变量。对入参变量的整理和过滤可以生成额外的基础变量;使用基础参数(比如帖子id),通过rpc调用,可以生成扩展的结果;对结果的提取可以生成额外的第二级变量;进一步对二级变量继续调用服务,可以生成更多的变量:比如通过图片模型结果过一些文本模型,但是随着层级的变深,整体服务呈现多级依赖关系,这也增加了整体的系统耗时。对于入参或者RPC请求结果的处理,全部可以在变量平台上进行操作,变量平台定义了规则引擎可以使用的变量及具体的实现方式。因为变量平台支持编辑代码,所以一般的变量都可以直接在变量平台编辑完成,而对相对复杂的模型调用,则可以封装通用的util方法,之后在变量平台直接使用这些方法。2.3 规则引擎平台组件是一个个简单的util静态方法,通过入参及调用组件生成扩展的变量;自此进行规则判断的『素材』准备好了,接下来需要使用这些变量配置规则,而核心的规则引擎平台就是使用这些变量,生成规则。规则引擎目前支持的运算规则:规则运算符:目前支持变量值与常量的比较,包含基本的>,=,
|
|