旧文回头来看,有不少地方比较模糊,惋惜我如今找不到jess的源代码了,不然能够好好再看看实现细节,先搬过来再说,之后在研究啦,做为入门凑合着看吧。node
Rete算法是Charles Forgy在1979年的论文中首次提出的,针对基于规则知识表现的模式匹配算法。目前来讲,大部分规则引擎仍是基于rete算法做为核心,但都有所改进,好比drool,jess等等,下面介绍rete算法的概念,一些术语,以及使用规则引擎须要注意的问题。算法
先来看看以下的表达式:服务器
(name-of-this-production
LHS /* one or more conditions */
-->
RHS /* one or more actions */
)网络
name-of-this-production就是规则,LHS(left hand side)一系列条件,RHS(right hand side)这个是咱们知足条件后应该执行的动做。数据结构
结合该图介绍几个概念:ide
production memory(PM)是由全部的production造成。性能
working memory(WM)由外界输入根据匹配算法造成的,反映了运行中的规则引擎的状态,记录各类数据, WM中每个item称为working memory element(WME) ,由外界的输入产生。测试
agenda负责匹配,冲突解决,执行动做。优化
rete是网络的意思(拉丁语),它将全部的规则最终解释(或编译)生成一个识别网络,其中包括了alpha网络,beta网络。alpha网络是根据LHS生成的网络,它根据外界的输入快速识别是否存在condition成立,而且跟其beta网络交互更新整个网络的状态,以下图:this
最基本的alpha网络就如上图所示,相似于这样,全部的condition被parse到这样的网络,当外界输入wme时,该wme会进入这样一个网络进行辨识,若是到达最底端,证实一个condition成立了,固然,如图这个网络算是最简单的实现了,实际规则引擎须要提供更快速的算法去辨识输入的wme,好比将图中color的各类值存入hashtable,或者是jumptable,又或者是trie tree。整个alpha network是一个巨大的字符串匹配和过滤网络,须要将各类数据结构组合在一块儿去实现海量condition状况下的快速匹配。各类规则引擎的实现又是不一致的,好比jess,以下图:
(defrule done
(TESTING)
(number ?number)
(TEST IS DONE)
(INIT CREDIT 5)
(CUSTOMER AGE ?age)
(has ?type "PP"))
=>
(assert (TEST COMPLETED)))
这个production的解释后生成的网络,这里咱们先注意红色的节点,这些节点就是alpha网络的节点,这个图只是描述了大体的过程,以第一列为例,第一个红色node表示输入是否匹配TESTING这个字符串,第二个node匹配在TESTING后面的参数数量(slot)是否匹配0,若是咱们assert TESTING进入WM,那么这个fact是能够匹配到done这个rule的第一个condition的,其余能够依次类推,值得注意的是最后一个condition,has是咱们自定义的function,相似这样的function,jess没有单独生成一列,只是将它做为CUSTOMER AGE ?age这一列的最后一个node,这样的condition有个特色就是须要执行一段代码去判断某个事实是否成立(不只仅只是作字符串的操做),这段代码不只仅是字符串的匹配,同时还具备实时性,相似这样的condition开发中须要注意,由于alpha network在运行期会不止一次去执行这个condition是否成立,这个是匹配算法的特性决定,因此,咱们须要用cache或者规则语言的特性去避免没必要要的执行code以提升性能。
下面贴个比较复杂的例子:
图太大,一个截不下来。。。。。。
下面咱们结合两个例子说说beta网络,当alpha网络过滤后condition成立,WME被传递到beta网络时,绿色的node就要发挥做用了,这个node就是join node,它有两个input,一个join node ,一个alpha node(红色),join node是由多个WME组成的,对于初始的join node 咱们称为left input adapter 如图中×××的node,该node是空的,那么第一个把这个node做为left input的join node就只包含了一个WME,下一个join node则包含了两个WME,以此类推。图中天蓝色的node上方的join node 彻底匹配了production执行须要的condition,因此这个rule就被激活等待执行了。
假设咱们须要编辑业务逻辑,那么最好的描述载体就是流程图,简单的流程图包含如下一些基本单元:起始节点,逻辑判断,执行动做,结束节点。这些节点能够完成最简单的业务逻辑描述,那么咱们把这些流程parse到规则的时候,咱们会怎么去作,第一个逻辑判断单元返回true,因而咱们执行某个动做,第二,三个逻辑判断单元返回true咱们执行某个动做,至关于会parse到两个规则,符合condition1,production1触发,符合condition2,3,production2触发,有了beta网络,咱们在触发production2时只须要判断condition2,3是否成立,对于更复杂的状况,beta网络提升了速度,避免了重复匹配。
开发中使用规则引擎也遇到些问题,总结以下:
1)规则引擎中对于特殊condition的处理,因为condition会在部分production中重复出现,因此会形成condition的重复匹配问题,影响了程序的性能,这个要结合项目去优化rule脚本的parse或者使用cache去提高性能。补充:能够将动态执行的condition放到LHS的最后,保证只有在必要的时候才会执行,固然具体状况还得看具体rule engine的实现啦
2)内存消耗问题,rete算法是空间换时间,因此对于内存的消耗是比较大的,特别是加载rule的时候(生成网络),在运行期内存会缓慢增加,因此gc效率须要注意,同时单个服务器所能承受的压力(多个WM)也跟规则引擎息息相关。
3)测试,对于使用规则去表达业务的系统,如何测试是必须解决的问题,对于这个问题,也只能保证基本的流程分支覆盖测试,对于复杂状况下的defect很难发现,不过有些原则须要注意,若是要使用规则引擎,咱们必须彻底以规则引擎为核心,对于业务逻辑必须尽量的抽取到规则引擎去实现,对于扩展实现的function粒度必须小且简单,不要再代码中去实现业务逻辑。
4)大部分的condition须要是不变的,也就是说基本信息须要保持稳定不变。好比某客户公司上属集团信用额度大于100w这样的condition,这个额度变化的频度不会很高,不须要去实时匹配。
5)remove WME production是较复杂的操做,规则较复杂时,应该尽可能少去作这样的操做。