规则引擎

发表于 2年以前  | 总阅读数:968 次

概念

规则引擎其实不是新兴起的东西了,这个概念的提出其实可以追溯到上世纪,规则引擎起源于基于规则的专家系统,专家系统这东西属于人工智能的范畴了,模仿人类的推理方式的推理引擎,是将逻辑规则应用于知识库以推断新信息的系统的一个组成部分。

先来看一下这个场景:

之前做会员场景的时候会遇到这种需求,根据用户购买的商品价格和品类,赠送不同的积分。

商品价格 赠送积分
<100 赠送20
<500 赠送80
>500 赠送200

如果我们写代码实现的话

const addPointsByOrderPrice = (order)=>{

if(order.price > 500 ){

add(order.account_id, 200);

} else if (order.price >100){

add(order.account_id, 80);

} else {

add(order.account_id, 20);

}

}

过了几天,运营同学说,这个效果不太好,我们再改下规则,变成100-200元的赠送20,200-500元赠送90,500-800赠送100.....如此类推一直到1w。

遇到这样的需求也是没办法了,总不能写n个if else。那就会想着,我把这个规则写配置中心或者数据库,不就ok了吗?

然后就有了以下的代码

let rules = await db.select("select * from rules");

const addPointsByOrderPrice = (order)=>{

for(let rule of rules){

if(order.price > rule.price){

add(order.account_id, rule.point);

break;

}

}

}

然后后面产品又脑洞大开了,觉得这个条件不够精细化,还要根据商品的标签属性,用户标签来判断。如果是新用户就乘二,如果商品是xx活动的特卖商品,积分就加多20。

这样下去正常人非得被产品需求搞死了。可以看出这里活动规则和代码已经耦合在一起了,即使用上配置中心,很多时候还是需要开发同学写硬编码去开发。

这时候就需要有个声明式语言,能把这个规则和玩法描述清楚。规则引擎主要完成的就是将业务规则从代码中分离出来。

在规则引擎中,利用规则语言将规则定义为if-then的形式,if中定义了规则的条件,then中定义了规则的结果。规则引擎会基于数据对这些规则进行计算,找出匹配的规则。这样,当规则需要修改时,无需进行代码级的修改,只需要修改对应的规则,可以有效减少代码的开发量和维护量。

目前最著名的开源规则引擎是Drools。

RETE算法

这是Drools里用到的一个核心算法。Rete算法是一种前向规则快速匹配算法,是一个用于产生式系统的高效模式匹配算法,其匹配速度与规则数目无关。解决的是两个问题:

  1. 大量重复的condition匹配效率的问题
  2. 规则冲突规范的问题

通过这个算法我们可以了解规则引擎的核心思想。

首先解释几个关于规则引擎的概念:

Fact(事实):对象之间和对象属性之间的关系

Rule(规则):由条件和结论构成的推理语句,一般表示为if…Then。一个规则的if部分称为LHS(left-hand-side),then部分称为RHS(right hand side)。

Module(模式):就是指IF语句的条件。这里IF条件可能是有几个更小的条件组成的大条件。模式就是指的不能在继续分割下去的最小的原子条件。

DSL(领域语言):领域专家只需要业务,而不需要关注技术

假设系统中有N条规则,平均每个规则的条件部分有P个模式,在某个时点有M个事实需要处理。则规则匹配要做的事情就是:对每一个规则r,判断当前的事实o是否满足LHS(r)=True,如果满足,则将规则r的实例r(o),即规则+满足该规则的事实,加到冲突集中等待处理。通常采取如下过程:

  • 从N条规则中取出一条r;

  • 从M个事实中取出P个事实的一个组合c;

  • 用c测试LHS(r),如果LHS(r(c))=True,将RHS(r(c))加入队列中;

  • 如果M个事实还存在其他的组合c,goto 3;

  • 取出下一条规则r,goto 2;

实际的问题可能更复杂,在规则的执行过程中可能会改变RHS的数据,从而使得已经匹配的规则实例失效或者产生新的满足规则的匹配,形成一种“动态”的匹配链。

目前常见的模式匹配算法包括Rete、Treat、Leaps,HAL,Matchbox等。

假设一个场景,物流分货物。货物的属性有重量,种类,收货地,是否加急。

按照规则引擎的三大概念来划分:

StockFact:该对象存放货物的基本信息。

SelectStockRule: 筛选规则

IF:
Weight < 10kg
Category != 易燃物
收货地 != 新疆
THEN
交给xx航班空运

Rete算法划分

Agenda:一旦一个业务对象匹配了一个规则,会形成该规则和该业务对象的一个议程。即StockFact要把该货物放在空运的事件。

Execution-Engine:业务对象匹配上一个规则后,业务对象执行规则结果的执行器。即将StockFact该货物放在空运中事件的执行器

Rete 算法可以被分为两个部分:规则编译和规则执行 。当 Rete 算法进行事实的断言时,包含三个阶段:匹配、选择和执行,称做 match-select-act cycle。本质上是利用空间换换时间,会消耗较多内存。

AlphaNode:例如。Weight < 10kg 这就是一个 alpha node 节点,当一条规则有多条字面条件,这些字面条件被链接到一起。

BetaNode:用来对2个对象进行对比、检查。比如这两个条件的组合

Weight < 10kg

&&

Category != 易燃物

约定BetaNode的2个输入称为左边(Join Node)和右边。左边通常是一个a list of objects,右边(NotNode)通常是 a single object。每个Bate节点都有自己的终端节点等组成。BetaNode 具有记忆功能。左边的输入被称为 Beta Memory,会记住所有到达过的语义。右边的输入成为 Alpha Memory

一个规则引擎最重要的是Patten Matcher。我们经常用的正则表达式就是一种模式匹配。

Patten Matcher流程展示

1.顺序为ABCDE。ABD为Alpha节点,CD为Beta节点。

2.从WM中拿出Fact,首先先匹配A,A如果条件符合,把Fact的引用存到A的Alpha Cache。A没有左引用的Beta节点,退出。

3.然后匹配B,B如果条件符合,把Fact的引用存到B的Alpha Cache。然后B有左引用的Beta节点,就是C。

4.C节点作为Beta节点,有左引用的节点A,然后找下Alpha Cache有没有A节点的引用。如果有,那就存到C节点对应的Beta节点。退出

5.到D节点的匹配,如果符合条件,把Fact的引用存到D的Alpha Cache。同样找到D的左引用Beta节点E,E的左引用为C。如果C的Beta Cache是否有C的引用,如果有证明所有条件符合,E的引用存在BetaCache中

6.该Fact匹配了这些规则,形成了一个议程,放入冲突区并执行结果。

那如果有多个规则被触发呢?

我们定义了多个规则,每个规则都有不同的显着性,当一条消息被断言时,它们将按照显着性(从高到低)的顺序触发。

PS:显着性是一个可以在规则上指定的选项,赋予它优先级并允许开发人员对激活的冲突解决方案进行一些控制。

Nodejs开源组件-Nools

上github链接noolsjs/nools[1]。首先要说明的是,Nools这个项目已经停止维护一段时间了,甚至谷歌都没有搜出什么有用的中文文档,都是有段历史的的外文文档,但是官方文档齐全。因此这里不建议大规模使用在生产环境,可能会误伤。

虽然不太能用,但是用他来理解规则引擎的概念也是比较好的,毕竟Nools也是使用Rete算法实现的。

var nools = require("nools");

var flow = nools.compile("./Demo2.nools"),

Param = flow.getDefined("Param");

session = flow.getSession(new Param(11))

.on('assert', function (result) {

console.log(result);//回调返回assert的内容,输出 result2

})

.on('modify', function (result) {

console.log(result, result.param1);//回调返回修改的值,输出{param1:21} 21(无参数note)

})

.match().then(function () {

console.log('end');//不管是否有规则满足都执行,输出end

});

可以看到这里有几个状态,assert,modify。

根据官方文档描述的是

  • assert (fact) - emitted when facts are asserted

  • retract (fact) - emitted when facts are retracted

  • modify (fact) - emitted when facts are modified

  • fire (name, rule) - emitted when an activation is fired.

使用这几个状态,我们可以轻易的在nools文件里控制网络的流向。

假设目前有nools文件如下

define Param { //作为规则的输入消息
param1 : 0,
note :'test for nothing',
constructor : function(p1){
    this.param1 = p1;
}

}

rule condition1 { //定义规则condition1

when { p:Param p.param1 <= 10;}

then { assert("result111");}

}

rule condition2 { //定义规则condition2

when { p:Param p.param1 > 10 && p.param1 <= 20;}

then {
//这些事件的触发都可以是多个
assert('result2'); //触发assert事件
//fire(p);
modify(p,function(){ //触发modify事件
p.param1 -= 10;
});
}

}

它定义了一个两个rule,一个是params <= 10, 一个是 params > 10 && params <=20;

这里不贴图了,直接看代码演示,从DSL语法来更近一步了解Rete网络。

场景设计

现在我们要设计一个抽奖规则可视化。

除了基础服务如抽奖服务,用户服务,还应该要考虑以下的问题:

  • 可视化规则编辑器

  • 规则自动化测试框架

  • 事实浏览器

  • mock服务

  • 规则管理和版本

  • 用户不敏感状态的缓存

  • 规则执行

如果要做到能用的话,这里仅需要关注AST和规则引擎即可。

第一部分是可视化规则编辑,虽然规则引擎把逻辑和业务代码分离开,但是DSL真的太不好阅读了。目标当然是方便配置,甚至可以不用开发介入就可以完成规则的配置。假设设计为只需要写这么一行简单易懂的话,就可以生成具体的DSL给规则引擎。

If

(老用户 为 真

和

活跃天数 大于 20)

或

新用户

Then

抽奖机会 + 1

这段话就很简单易懂。这里要引入Parse模块,把这段话转化成DSL。

其实就是语法解析,这里考虑使用Pegjs这个库实现。这里不做进一步的介绍了,有兴趣可以参考https://pegjs.org/online。更高阶的做法是做成拖拽的样式更方便运营同学使用。

第二部分是规则引擎,那就可以自由选择nools或者json-rules-engine来实现。(json-rules-engine也提供了对应的开源编辑器,如果图方便可以直接用这个可视化编辑,虽然我个人觉得很难用)。

以上提供了一个规则生成器的思路,往细里分析的话会发现,以上我定义的都是静态规则,实际生产环境上一定会有动态规则的出现,这里就交给大家在实际业务中去思考了。

杂谈

业界里使用规则引擎的场景并不少,特别是现在中台概念提出一段时间后,很多复杂逻辑都整合到一个大型系统中。规则引擎的引入能减少很多代码复杂度和编码工作。

规则引擎Tob的标杆就要数IBM的iLog,跟中移动的合作公司的朋友了解过,广东移动上新的计费和套餐就是用这一套的,很多保险公司也是在用iLog。像淘宝美团电商类的优惠券规则,也都会用到规则引擎,不过一般都是自研的。银行的金融风控也会有规则引擎,甚至一些APP像抖音,BigoLive这种短视频APP里也会有规则引擎,模型去做识别,然后作为动态规则去加载对应的图形。

虽然网上查规则引擎,基本都是出来Drools,但是很多时候实际选型上根本不会选它,主要因为

  • Drools相关的组件太多,需要逐个研究才知道是否需要
  • Drools逻辑复杂,不了解原理,一旦出现问题排查难度高
  • Drools需要编写DSL(领域特殊语言)文件,学习成本高

所以像美团,淘宝系这些团队在规则引擎的选型上会更倾向于使用动态脚本引擎,像Groovy,aviator,easyRule这些,这些引擎DSL的写法跟java相似,组件生态跟java无缝贴合。

小规模的规则引擎,还是推荐自己写或者用轻量级的框架要来的快,毕竟很多时候都不会接触到上百万条规则的场景。如果是自己写的话可以考虑直接设计决策树,又能兼容可视化又方便遍历。js的组件可以参考一下CacheControl/json-rules-engine[2]也是一个不错的选择。

遗留问题:

  • 如何选定合适组件
  • 规则可视化配置
  • 规则维护
  • 规则执行效率

引用文档

PEG.js 介绍与基础使用[3]

nools[4]

[转]规则匹配--Rete 算法原理及实现_我的代码管家---houwenbin的专栏-CSDN博客_rete[5]

别再说你不懂规则引擎啦![6]

RETE算法初窥[7]

参考资料

[1]noolsjs/nools: https://github.com/noolsjs/nools#flow

[2]CacheControl/json-rules-engine: https://github.com/CacheControl/json-rules-engine

[3]PEG.js 介绍与基础使用: https://zhuanlan.zhihu.com/p/49833910

[4]nools: http://noolsjs.com/#facts-retract

[5][转]规则匹配--Rete 算法原理及实现_我的代码管家---houwenbin的专栏-CSDN博客_rete: https://blog.csdn.net/houwenbin1986/article/details/93893684

[6]别再说你不懂规则引擎啦!: https://juejin.cn/post/6942310146882306084

[7]RETE算法初窥: https://blog.abstiger.com/introduce-rete-algorithm/

本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/t11C5s6OZOV3o0U2XhIehQ

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:7月以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:7月以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:7月以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:7月以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:7月以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:7月以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:7月以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:7月以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:7月以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:7月以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:7月以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:7月以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:7月以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:7月以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:7月以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:7月以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:7月以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:7月以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:7月以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:7月以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  236876次阅读
vscode超好用的代码书签插件Bookmarks 1年以前  |  6890次阅读
 目录