规则引擎概述及选型
⽂章⽬录
⼀、规则引擎概述:
规则引擎由推理引擎发展⽽来,是⼀种嵌⼊在应⽤程序中的组件,实现了将业务决策从应⽤程序代码中分离出来,并使⽤预定义的语义模块编写业务决策。
规则引擎具体执⾏可以分为接受数据输⼊,解释业务规则,根据业务规则做出业务决策⼏个过程。
使⽤规则引擎可以把复杂、冗余的业务规则同整个⽀撑系统分离开,做到架构的可复⽤移植。
规则引擎通常允许您在不重新启动系统或部署新的可执⾏代码的情况下更改规则。规则引擎不是⼀个新的东西的魔法盒,它旨在成为⼀个提供更⾼级别抽象的⼯具,以便您可以更少地关注开发细节。
Rules engines are not really intended to handle workflow or process executions nor are workflow engines or process management tools designed to do rules.
规则引擎的起源:
Java规则引擎起源于基于规则的专家系统(RBES),⽽基于规则的专家系统⼜是专家系统的其中⼀个分⽀。专家系统属于⼈⼯智能的范畴,它模仿⼈类的推理⽅式,使⽤试探性的⽅法进⾏推理,并使⽤⼈类能理解的术语解释和证明它的推理结论。专家系统有很多分类:神经⽹络、基于案例推理和基于规则系统等。
RBES包括三部分:Rule Base(knowledge base)、Working Memory(fact base)和Inference Engine(推理引擎)。它们的结构如下所⽰:
推理引擎包括三部分:模式匹配器(Pattern Matcher)、议程(Agenda)和执⾏引擎(Execution Engine)。推理引擎通过决定哪些规则满⾜事实或⽬标,并授予规则优先级,满⾜事实或⽬标的规则
被加⼊议程。模式匹配器决定选择执⾏哪个规则,何时执⾏规则;议程管理模式匹配器挑选出来的规则的执⾏次序;执⾏引擎负责执⾏规则和其他动作。
和⼈类的思维相对应,推理引擎存在两者推理⽅式:演绎法(Forward- Chaining)和归纳法(Backward-Chaining)。演绎法从⼀个初始的事实出发,不断地应⽤规则得出结论(或执⾏指定的动作)。⽽归纳法则是根据假设,不断地寻符合假设的事实。Rete算法是⽬前效率最⾼的⼀个Forward-Chaining推理算法,许多Java规则引擎都是基于 Rete算法来进⾏推理计算的。
推理引擎的推理步骤如下:
⑴将初始数据(fact)输⼊Working Memory。
⑵使⽤Pattern Matcher⽐较规则库(rule base)中的规则(rule)和数据(fact)。
⑶如果执⾏规则存在冲突(conflict),即同时激活了多个规则,将冲突的规则放⼊冲突集合。
⑷解决冲突,将激活的规则按顺序放⼊Agenda。
⑸使⽤执⾏引擎执⾏Agenda中的规则。重复步骤⑵⾄⑸,直到执⾏完毕所有Agenda中的规则。
上述即是规则引擎的原始架构,Java规则引擎就是从这⼀原始架构演变⽽来的。
规则引擎的相关构件:
规则引擎是⼀种根据规则中包含的指定过滤条件,判断其能否匹配运⾏时刻的实时条件来执⾏规则中所规定的动作的引擎。与规则引擎相关的有四个基本概念,为更好地理解规则引擎的⼯作原理,下⾯将对这些概念进⾏逐⼀介绍。
⑴信息元(Information Unit)
信息元是规则引擎的基本建筑块,它是⼀个包含了特定事件的所有信息的对象。这些信息包括:消息、产⽣事件的应⽤程序标识、事件产⽣事件、信息元类型、相关规则集、通⽤⽅法、通⽤属性以及⼀些系统相关信息等等。
⑵信息服务(Information Services)
信息服务产⽣信息元对象。每个信息服务产⽣它⾃⼰类型相对应的信息元对象。即特定信息服务根据信息元所产⽣每个信息元对象有相同的格式,但可以有不同的属性和规则集。需要注意的是,在⼀台机器上可以运⾏许多不同的信息服务,还可以运⾏同⼀信息服务的不同实例。但⽆论如何,每个信息服务只产⽣它⾃⼰类型相对应的信息元。
⑶规则集(Rule Set)
顾名思义,规则集就是许多规则的集合。每条规则包含⼀个条件过滤器和多个动作。⼀个条件过滤器可以包含多个过滤条件。条件过滤器是多个布尔表达式的组合,其组合结果仍然是⼀个布尔类型的。在程序运⾏时,动作将会在条件过滤器值为真的情况下执⾏。除了⼀般的执⾏动作,还有三类⽐较特别的动作,它们分别是:放弃动作(Discard Action)、包含动作(Include Action)和使信息元对象内容持久化的动作。java加密方式有哪些
⑷队列管理器(Queue Manager)
队列管理器⽤来管理来⾃不同信息服务的信息元对象的队列。
如下图所⽰,处理过程分为四个阶段进⾏:信息服务接受事件并将其转化为信息元,然后这些信息元被传给队列管理器,最后规则引擎接收这些信息元并应⽤它们⾃⾝携带的规则加以执⾏,直到队列管理器中不再有信息元。
规则引擎的⼯作机制:
下⾯研究规则引擎的内部处理过程。如下图所⽰,规则引擎从队列管理器中依次接收信息元,然后依规则的定义顺序检查信息元所带规则集中的规则。规则引擎检查第⼀个规则并对其条件过滤器求值,如果值为假,所有与此规则相关的动作皆被忽略并继续执⾏下⼀条规则。如果第⼆条规则的过滤器值为真,所有与此规则相关的动作皆依定义顺序执⾏,执⾏完毕继续下⼀条规则。该信息元中的所有规则执⾏完毕后,信息元将被销毁,然后从队列管理器接收下⼀个信息元。在这个过程中并未考虑两个特殊动作:放弃动作(Discard Action)和包含动作(Include Action)。放弃动作如果被执⾏,将会跳过其所在信息元中接下来的所有规则,并销毁所在信息元,规则引擎继续接收队列管理器中的下⼀个信息元。包含动作其实就是动作中包含其它现存规则集的动作。包含动作如果被执⾏,规则引擎将暂停并进⼊被包含的规则集,执⾏完毕后,规则引擎还会返回原来暂停的地⽅继续执⾏。这⼀过程将递归进⾏。
Java规则引擎的⼯作机制与上述规则引擎机制⼗分类似,只不过对上述概念进⾏了重新包装组合。J
ava规则引擎对提交给引擎的Java 数据对象进⾏检索,根据这些对象的当前属性值和它们之间的关系,从加载到引擎的规则集中发现符合条件的规则,创建这些规则的执⾏实例。这些实例将在引擎接到执⾏指令时、依照某种优先序依次执⾏。⼀般来讲,Java规则引擎内部由下⾯⼏个部分构成:⼯作内存(Working Memory)即⼯作区,⽤于存放被引擎引⽤的数据对象集合;规则执⾏队列,⽤于存放被激活的规则执⾏实例;静态规则区,⽤于存放所有被加载的业务规则,这些规则将按照某种数据结构组织,当⼯作区中的数据发⽣改变后,引擎需要迅速根据⼯作区中的对象现状,调整规则执⾏队列中的规则执⾏实例。Java规则引擎的结构⽰意图如下图所⽰。
当引擎执⾏时,会根据规则执⾏队列中的优先顺序逐条执⾏规则执⾏实例,由于规则的执⾏部分可能会改变⼯作区的数据对象,从⽽会使队列中的某些规则执⾏实例因为条件改变⽽失效,必须从队列中撤销,也可能会激活原来不满⾜条件的规则,⽣成新的规则执⾏实例进⼊队列。于是就产⽣了⼀种“动态”的规则执⾏链,形成规则的推理机制。这种规则的“链式”反应完全是由⼯作区中的数据驱动的。
任何⼀个规则引擎都需要很好地解决规则的推理机制和规则条件匹配的效率问题。规则条件匹配的效率决定了引擎的性能,引擎需要迅速测试⼯作区中的数据对象,从加载的规则集中发现符合条件的规则,⽣成规则执⾏实例。1982年美国卡耐基·梅隆⼤学的 Charles L. Forgy发明了⼀种叫Rete算法,很好地解决了这⽅⾯的问题。⽬前世界顶尖的商⽤业务规则引擎产品基本上都使⽤Rete算法。
Java规则引擎API(JSR-94):
过去⼤部分的规则引擎开发并没有规范化,有其⾃有的API,这使得其与外部程序交互集成不够灵活。转⽽使⽤另外⼀种产品时往往意味需要重写应⽤程序逻辑和API调⽤,代价较⼤。为了使规则引擎技术标准化,Java社区制定了Java规则引擎API(JSR-94)规范。它为Java平台访问规则引擎定义了⼀些简单的API。
Java规则引擎API由javax.rules包定义,是访问规则引擎的标准企业级API。Java规则引擎API允许客户程序使⽤统⼀的⽅式和不同⼚商的规则引擎产品交互,就像使⽤JDBC编写独⽴于⼚商访问不同的数
据库产品⼀样。Java规则引擎API包括创建和管理规则集合的机制,在Working Memory中添加,删除和修改对象的机制,以及初始化,重置和执⾏规则引擎的机制。
Java规则引擎API分为两个主要部分:规则管理API(the rules administration API)和运⾏时客户API(the Runtime client API)。
⑴规则管理API:
规则管理API在javax.rules.admin中定义,包括装载规则以及与规则对应的动作(执⾏集 execution sets)以及实例化规则引擎。规则可以从外部资源中装载,⽐如URI,Input streams,XML streams和readers等等。同时管理API提供了注册和取消注册执⾏集以及对执⾏集进⾏维护的机制。使⽤admin包定义规则有助于对客户访问运⾏规则进⾏控制管理,它通过在执⾏集上定义许可权使得未经授权的⽤户⽆法访问受控规则。
管理API使⽤类RuleServiceProvider来获得规则管理(RuleAdministrator)接⼝的实例。规则管理接⼝提供⽅法注册和取消注册执⾏集。规则管理器(RuleAdministrator)提供了本地和远程的RuleExecutionSetProvider。在前⾯已提
及,RuleExecutionSetProvider负责创建规则执⾏集。规则执⾏集可以从如XML streams,input strea
ms等来源中创建。这些数据来源及其内容经汇集和序列化后传送到远程的运⾏规则引擎的服务器上。⼤多数应⽤程序中,远程规则引擎或远程规则数据来源的情况并不多见。为了避免这些情况中的⽹络开销,API规定了可以从运⾏在同⼀JVM中规则库中读取数据的本地RuleExecutionSetProvider。
规则执⾏集接⼝除了拥有能够获得有关规则执⾏集的⽅法,还有能够检索在规则执⾏集中定义的所有规则对象。这使得客户能够知道规则集中的规则对象并且按照⾃⼰需要来使⽤它们。
⑵运⾏时客户API:
运⾏时API定义在javax.rules包中,为规则引擎⽤户运⾏规则获得结果提供了类和⽅法。运⾏时客户只能访问那些使⽤规则管理API注册过的规则,运⾏时API帮助⽤户获得规则对话并且在这个对话中执⾏规则。
运⾏时API提供了对⼚商规则引擎API实现的类似于JDBC的访问⽅法。规则引擎⼚商通过类RuleServiceProvider(类RuleServiceProvider提供了对具体规则引擎实现的运⾏时和管理API的访问)将其规则引擎实现提供给客户,并获得RuleServiceProvider唯⼀标识规则引擎的URL。
URL推荐标准⽤法是使⽤类似“ulesengine.rules.RuleServiceProvider”这样的Internet域名空间,这将有助于访问URL的唯⼀性。类RuleServiceProvider内部实现了规则管理和运⾏
时访问所需的接⼝。所有的RuleServiceProvider要想被客户所访问都必须⽤RuleServiceProviderManager进⾏注册。注册⽅式类似于JDBC API的DriverManager和Driver。
运⾏时接⼝是运⾏时API的关键部分。运⾏时接⼝提供了⽤于创建规则会话(RuleSession)的⽅法,规则会话如前所述是⽤来运⾏规则的。运⾏时API同时也提供了访问在service provider注册过的所有规则执⾏集(RuleExecutionSets)。规则会话接⼝定义了客户使⽤的会话的类型,客户根据⾃⼰运⾏规则的⽅式可以选择使⽤有状态会话或者⽆状态会话。
⽆状态会话的⼯作⽅式就像⼀个⽆状态会话bean。客户可以发送单个输⼊对象或⼀列对象来获得输出对象。当客户需要⼀个与规则引擎间的专⽤会话时,有状态会话就很有⽤。输⼊的对象通过addObject() ⽅法可以加⼊到会话当中。同⼀个会话当中可以加⼊多个对象。对话中已有对象可以通过使⽤updateObject()⽅法得到更新。只要客户与规则引擎间的会话依然存在,会话中的对象就不会丢失。
RuleExecutionSetMetaData接⼝提供给客户让其查规则执⾏集的元数据(metadata)。元数据通过规则会话接⼝(RuleSession Interface)提供给⽤户。
Java规则引擎API安全问题:
规则引擎API将管理API和运⾏时API加以分开,从⽽为这些包提供了较好粒度的安全控制。规则引擎API并没有提供明显的安全机制,它可以和J2EE规范中定义的标准安全API联合使⽤。安全可以由以下机制提供,如Java 认证和授权服务(JAAS),Java加密扩展(JCE),Java安全套接字扩展(JSSE),或者其它定制的安全API。使⽤JAAS可以定义规则执⾏集的许可权限,从⽽只有授权⽤户才能访问。
异常与⽇志:
规则引擎API定义了javax.rules.RuleException作为规则引擎异常层次的根类。所有其它异常都继承于这个根类。规则引擎中定义的异常都是受控制的异常(checked exceptions),所以捕获异常的任务就交给了规则引擎。规则引擎API没有提供明确的⽇志机制,但是它建议将Java Logging API⽤于规则引擎API。
规则引擎的优势:
①声明式编程。
规则引擎允许你描述做什么⽽不是如何去做。(规则⽐编码更容易阅读)
②逻辑与数据分离。
数据保存在系统对象中,逻辑保存在规则中。这根本性的打破了⾯向对象系统中将数据和逻辑耦合起来的局⾯。这样做的结果是,将来逻辑发⽣改变时更容易被维护,因为逻辑保存在规则中。这点在逻辑是跨领域或多领域中使⽤时尤其有⽤。通过将逻辑集中在⼀个或数个清晰的规则⽂件中,取代了之前分散在代码中的局⾯。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论