详解如何使用Golang实现自定义规则引擎

   日期:2024-12-27     作者:caijiyuan      
核心提示:规则引擎的功能可以简化为当满足一些条件时触发一些操作,通常使用 DSL 自定义语法来表述。规则引擎需要先解析 DSL 语法形成语法

规则引擎的功能可以简化为当满足一些条件时触发一些操作,通常使用 DSL 自定义语法来表述。规则引擎需要先解析 DSL 语法形成语法树,然后遍历语法树得到完整的语法表达式,最后执行这些语法表达式完成规则的执行。

本文以gengine来探讨如何设计和实现一个自定义规则引擎。

为了满足基本的业务规则需求,规则引擎应该要支持的语句有:

  • 数学运算(+、-、*、/)
  • 逻辑运算(&&、||、!)
  • 比较运算(==、!=、>、<、>=、<=)
  • 条件(IF ELSE)
  • 循环 (FOR)
  • 对象属性访问(对象。属性)
  • 方法调用(func ())

规则的 DSL 语法定义应该简单明了,gengine 使用了开源的语法解析器 Antlr4 来定义和解析规则语法。

规则的 DSL 基本语法格式如下:

其中规则体为具体规则语句,由上述的 逻辑与算术运算、流程控制、高级语句 组合而成。

例如,判断为一个大额异常订单的规则体:

Antlr4 解析器语法定义文件后缀名为.g4,以下内容为解析器的语法定义,解析器根据语法定义去逐行解析生成语法树。

这里省略了一些非核心的语法定义并做了简化,完整内容查看 gengine.g4。

如,判断为一个大额异常订单的规则:

语法解析器解析之后,生成语法树:

解析器生成语法树之后,只需要遍历语法树即可得到完整的语句表达式。Antlr4 解析器会生成 Listener 接口,这些接口在遍历语法树时会被调用。

可以发现在遍历语法树时,每个节点都有 EnterXXX() 和 ExitXXX() 方法存在,是成对出现的。

因此要遍历语法树只需要实现 gengineListener 接口即可,gengine 巧妙的引入结构,遍历完语法树后(树的递归遍历就是进栈出栈过程),就得到了完整的规则语句表达式。这里只列举部分方法,完整实现见 gengine_parser_listener。

详解如何使用Golang实现自定义规则引擎

gengine 通过解析器解析规则内容之后,规则的数据结构如下:

全局的 hashmap 以规则名为 key,规则体为 value,规则体中的 ruleContent 为该规则所有的语句表达式列表,列表中的值指向具体的语句表达式实体,语句表达式实体由 逻辑与算术运算、流程控制(IF、FOR)等基本语句组成。

其实遍历语法树的过程中,将规则的执行逻辑也放入 ExitXXX() 方法,这样就能一并完成规则的解析和执行。但是 gengine 没有这么做,而是将规则的解析和执行解耦,因为规则的解析往往只需要初始化一次,或者在规则有变更时热更新解析,而规则的执行则是在需要校验规则的时候。

从 gengine 的规则数据结构可知,只需要遍历全局的 hashmap,即可按顺序执行所有的规则(顺序模式),执行每一个规则后会通过方法记录执行结果:

对于某一个规则的执行,则会去遍历规则体 ruleContent 的所有语句表达式列表,然后按顺序去执行该规则下的所有语句表达式:

gengine 为每个语句类型都实现了 Evaluate() 方法,这里只讨论 IF 语句的执行:

其中条件表达式为计算条件表达式的值:

递归执行到原子表达式时,就可以得到该原子表达式的值以结束递归:

在上下文中注入自定义对象后,就可以在规则中使用注入的对象。使用例子:

现在来看下 gengine 的具体实现,主要是使用反射特性:

gengine 解析规则时会将自定义对象标记为类型,通过 GetValue() 获取自定义对象属性值:

同样在上下文中注入自定义方法后,也可以在规则中使用注入的方法。使用例子:

gengine 自定义方法的注入也是使用反射来实现,自定义方法的注入同自定义对象一样也是使用 Add() 方法注入。

gengine 解析规则时会将自定义方法标记为类型:

通常情况下顺序模式执行即可满足要求,但是当规则数量比较大时,顺序执行的耗时就会比较长。

规则引擎在执行所有规则的时候,其实是遍历全局的 hashmap 然后再顺序执行每一个规则,由于每个规则之间没有依赖关系,因此可以用每一个规则一个协程来并发执行。

有了规则引擎之后,很多在业务代码中的 if-else、switch 硬编码,都能抽象为规则并使用规则引擎,这样能通过配置规则代替硬编码,能极大地缩短变更上线时间。

业务风控

通过业务数据分析,可以抽象出用户异常行为的规则:

然后,风控系统在判断是否为风险操作时,只需要规则引擎加载并执行风控规则,即可得到结果。想要提高风控系统的准确性,只需要不断地迭代完善风控规则。

规则引擎在业务风控的实践,可以参考 基于准实时规则引擎的业务风控实践。

运营活动

拿最常见的抽奖和做任务 2 种运营活动来说,都可以将具体活动逻辑抽象为业务规则:① 抽奖,不同的人&不同的场景对应不同的奖池(中奖概率与奖品集合规则);② 做任务,任务领取规则、任务完成指标动态可配(任务规则);

内容分发

针对某些特定的用户或者某种场景的用户,下发特定的展示内容或者推送短信等触达消息,都可以将这些特定用户的逻辑梳理为内容分发规则。

     本文地址:http://w.yusign.com/tjnews/2887.html    述古往 http://w.yusign.com/static/ , 查看更多
 
特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。

举报收藏 0打赏 0
 
更多>同类生活信息

相关文章
最新文章
推荐文章
推荐图文
生活信息
点击排行
{
网站首页  |  关于我们  |  联系方式  |  用户协议  |  隐私政策  |  版权声明  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  鄂ICP备2020018471号