您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
business rule engine研究
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
business rule engine研究
自猿其说Tech
2021-05-28
IP归属:未知
3753浏览
计算机编程
# 1.概述 目的:学习并传播business rule engine 的应用技巧,以便于在项目中应用。 本文面向的读者: 系统架构师,业务架构师。 # 2.需求 ## 2.1 认识rule 这是 drools engine 的一条规则, ``` rule "High Risk" when Driver( male == true, age >= 16, age <= 25 ) Car ( style == Style.SPORT, color == Color.RED ) then $p.increasePremium( new Percentage( 20 ) ); end ``` 规则是由 condition : action 2部分构成的。这是对高风险的保单增加保费的一条规则。 ## 2.2 规则数量多,经常变化的规则的场景 规则是由业务运营人员编辑的,譬如以下是sap 的一个规则编辑界面: ![](//img1.jcloudcs.com/developer.jdcloud.com/87f73285-b41e-4f4f-b07d-6c0cab89c54620210528140253.png) 可以这么说, business rule engine ,它不像程序员的工具,它像是业务运营人员的工具。 # 3.案例研究 ## 3.1 案例 折扣计算:对于购物车超过100元的订单,给与10% 的折扣。 规则如下: ``` package com.jdl.kili.demodrools.shop dialect "mvel" import com.sample.DroolsShop.Customer import com.sample.DroolsShop.Product import com.sample.DroolsShop.Purchase import com.sample.DroolsShop.Discount rule "Purchase notification" salience 10 when $c : Customer() $p : Purchase( customer == $c ) then System.out.println( "Customer " + $c.name + " just purchased " + $p.product.name ); end rule "Discount removed notification" when $c : Customer() not Discount( customer == $c ) then $c.discount = 0; System.out.println( "Customer " + $c.name + " now has a discount of " + $c.discount ); end rule "Discount awarded notification" when $c : Customer() $d : Discount( customer == $c ) then System.out.println( "Customer " + $c.name + " now has a discount of " + $d.amount ); end rule "Apply 10% discount if total purchases is over 100" no-loop true dialect "java" when $c : Customer() $i : Double(doubleValue > 100) from accumulate ( Purchase( customer == $c, $price : product.price ), sum( $price ) ) then $c.setDiscount( 10 ); insertLogical( new Discount( $c, 10 ) ); System.out.println( "Customer " + $c.getName() + " now has a shopping total of " + $i ); end ``` 用户修改购物车: ``` KieSession ksession = kc.newKieSession("ksession-shop-rules"); Customer mark = new Customer( "mark",0 ); ksession.insert( mark ); Product shoes = new Product( "shoes",60 ); ksession.insert( shoes ); Product hat = new Product( "hat",60 ); ksession.insert( hat ); ksession.insert( new Purchase( mark,shoes ) ); FactHandle hatPurchaseHandle = ksession.insert( new Purchase( mark,hat ) ); ksession.fireAllRules(); ksession.delete( hatPurchaseHandle ); System.out.println( "Customer mark has returned the hat" ); ksession.fireAllRules(); ``` 规则引擎计算折扣输出的过程记录: ``` Customer mark just purchased shoes Customer mark just purchased hat Customer mark now has a discount of 0 Customer mark now has a shopping total of 120.0 Customer mark now has a discount of 10 Customer mark has returned the hat Customer mark now has a discount of 0 ``` ## 3.2 典型的场景 ![](//img1.jcloudcs.com/developer.jdcloud.com/7736bbeb-c7ad-4629-9930-e83fd606dd5320210528140537.png) 以上这些场景,都有可能适合使用规则引擎: - 客户细分 - 促销报价 - 费用计算 - 生成产品目录 # 4.rete 算法 ## 4.1 Rete算法 的原理和场景 很厉害的原因: 可扩展性,性能不会随着规则数量降低太多。 这个好处是巨大的, 写一百条规则,你再追加1条的时候,这条规则与之前规则的冲突,规则引擎可以帮你分析,可以合并优化的,可以帮你优化。 ### 4.1.1算法的原理 网络节点合并,避免重复计算 空间换时间,记录中间结果,事实变化的时候, 避免重复计算 ### 4.1.2某些不一定适用的场景 - 规则少 - 规则之间没有关系 ## 4.2 rete 算法细节 示意图: ![](//img1.jcloudcs.com/developer.jdcloud.com/fbb33d11-b5d6-410e-8841-32339d0ecf2120210528140654.png) 网络内部分了2种节点: type,select 。 状态的保存,分为alpha memory, beta memory。 2.1 节增加保费的 drools rete 网络示意如下: ![](//img1.jcloudcs.com/developer.jdcloud.com/4ac41793-8a00-4074-a1e8-a27084a82e2f20210528140730.png) ### 4.2.1 合并网络 示意图: ![](//img1.jcloudcs.com/developer.jdcloud.com/29d7949b-dad9-4f52-b788-aaa7851bd09120210528140814.png) 2.1节的案例,譬如增加一条规则: ``` rule "Middle Risk" when driver: Driver( male == true, age >= 16, age <= 25 ) car: Car ( style == Style.SPORT, color == Color.GRAY ) then $p.increasePremium( new Percentage( 15 )); end ``` 则合并为如下drools rete网络: ![](//img1.jcloudcs.com/developer.jdcloud.com/4d1e2b1a-041e-4c35-a1f1-82066db6834d20210528140911.png) 详细的rete 网络编译过程,不再详述。本文读者只要记住rete 算法的原理:网络优化以及存储中间状态即可。 ## 4.3Rete算法的特点 Rete算法有几个特点: ①节点共享 不同规则之间含有相同的模式,可以共享节点。 ②状态保存 事实集合中的每次变化,其匹配后的状态都被保存在alpha和beta节点中。在下一次事实集合发生变化时,大多数的结果都不需要变化,rete算法通过保存状态,避免了重复计算。 ③latency 不稳定,随着规则规模和复杂度区别 ## 4.4 程序员如何理解business rule engine ①这不是一个类似 log4j, fastjson 之类,面向程序员的工具, 这是一个类似excel 一样的有应用属性的应用工具。 ②与求解器 (譬如 lpsolver)的异同: 相同点:都是描述性编程。 不同点: 求解器的模型一般不需要动态 , 规则引擎应用场景下,规则基本都是需要动态编写。 虽然如此, 程序员 ①可以改进business rule engine工具本身,可以做一些监控分析工具。 ②在规则虽然变化但是不是很频繁的场景,可以借助对于算法和工具的理解,做优化规则的工具。 # 5.系统是否使用business rule engine? ## 5.1 关键因素 系统设计的时候, 是否采用规则引擎? 关键的因素: 运营人员经常编辑的规则集合,而且规则集合有一定的规模和复杂性 ## 5.2 能否用好规则引擎 有入门门槛,包括:熟悉选用的rule engine 的性能特性,优化技巧 # 6.工具 ## 6.1商业性的规则引擎 主流的业务工具都有规则引擎的支持。 - sap - ibm - oracle - microsoft ## 6.2 drools 的一个demo Drools 是最活跃的开源规则引擎; ``` <dependency> <groupId>org.drools</groupId> <artifactId>drools-core</artifactId> <version>7.39.0.Final</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-compiler</artifactId> <version>7.39.0.Final</version> </dependency> <dependency> <groupId>org.kie</groupId> <artifactId>kie-internal</artifactId> <version>7.39.0.Final</version> </dependency> ``` ``` rule "Check Client Object" when $k:Keyword($v : value) $c:ClientObject( descr matches $v ) then $c.setPass($k.isResult()); System.out.println("Check Client Object fired"); end ``` ``` public class RuleParser { private static final Logger logger = LoggerFactory.getLogger(RuleParser.class); InternalKnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); public void init(String[] rules){ KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); for ( int i = 0; i < rules.length; i++ ) { String ruleFile = rules[i]; logger.info( "Loading file: " + ruleFile ); kbuilder.add( ResourceFactory.newClassPathResource( ruleFile, RuleParser.class ), ResourceType.DRL ); } Collection<KiePackage> pkgs = kbuilder.getKnowledgePackages(); kbase.addPackages( pkgs ); } public void process(List<Keyword> keywords, ClientObject clientObject){ KieSession session = kbase.newKieSession(); for(Keyword keyword:keywords){ session.insert(keyword); } session.insert(clientObject); session.fireAllRules(); } } ``` ClientObject 的descr 与 某个Keyword 中的 value 相等的话,则触发规则。 本文重点不是drools 的使用,drools 的介绍就到这里。 ## 6.3 drools 的性能 drools 的功能和性能与 商业的引擎有差距。但是,因为源码公开,也有一些定制优化的空间。 那有没有类似redis 那样的benchmark ? drools 有自己的benchmark 。但是bench mark 的设计仅仅是针对drools 自己优化的场景。 到具体场景,需要具体分析和测试。 # 7.结论 business rules engine 是一个应用工具, 时常动态编辑规则的场景是恰当的场景。 ------------ ###### 自猿其说Tech-JDL京东物流技术发展部 ###### 作者:中台技术部-仓储平台组 李建奇 ------------ 参考: rete算法介绍 https://core.ac.uk/download/pdf/301344584.pdf https://medium.com/elixir-bytes/logic-programming-the-infamous-rete-algorithm-in-elixir-b2fb4de85e5e https://www.sparklinglogic.com/rete-algorithm-demystified-part-1/ https://blog.csdn.net/houwenbin1986/article/details/93893684 https://www.jianshu.com/p/3e9afe9e0617 http://alvarestech.com/temp/fuzzyjess/Jess60/Jess70b7/docs/rete.html 这是用scala 实现的一个rete 算法的教学代码。 https://github.com/daveray/rooscaloo 性能 https://www.sparklinglogic.com/technical-series-decision-engine-performance/ https://www.bpminstitute.org/resources/articles/rete-necessary-business-rules-why-you-should-care https://medium.com/nerd-for-tech/how-to-run-100k-rules-in-drools-7b9308e75687 如何分析business rule https://www.brcommunity.com/articles.php?id=b551 http://160592857366.free.fr/joe/ebooks/tech/Wiley%20Business%20Rules%20Management%20and%20Service%20Oriented%20Architecture.pdf 案例 https://www.brcommunity.com/articles.php?id=b716, 医学领域,筛选病人的决策表 https://www.businessrulesgroup.org/brmanifesto.htm , 构建基于规则的系统的准则 https://www.infoq.com/articles/Rule-Engines/ https://www.brcommunity.com/articles.php?id=n014 , 通讯行业 https://www.brcommunity.com/articles.php?id=b064 , crm https://www.sparklinglogic.com/rete-algorithm-demystified-part-2/ , 折扣 http://www.mastertheboss.com/jboss-jbpm/drools/jboss-drools-tutorial ,折扣 https://www.youtube.com/watch?v=dA-7GlycA1U , sap business rule 教学 是否使用rule engine http://herzberg.ca.sandia.gov/guidelines.shtml https://www.hyperon.io/guide/business-rules-engines 编写规则的技巧 https://www.brcommunity.com/articles.php?id=b778 https://www.brcommunity.com/features.php?id=301 工具: https://www.drools.org/ , 开源的引擎
原创文章,需联系作者,授权转载
上一篇:Flutter状态管理之InheritedWidget&Provider
下一篇:深入JDK中的Optional
相关文章
Taro小程序跨端开发入门实战
Flutter For Web实践
配运基础数据缓存瘦身实践
自猿其说Tech
文章数
426
阅读量
2150053
作者其他文章
01
深入JDK中的Optional
本文将从Optional所解决的问题开始,逐层解剖,由浅入深,文中会出现Optioanl方法之间的对比,实践,误用情况分析,优缺点等。与大家一起,对这项Java8中的新特性,进行理解和深入。
01
Taro小程序跨端开发入门实战
为了让小程序开发更简单,更高效,我们采用 Taro 作为首选框架,我们将使用 Taro 的实践经验整理了出来,主要内容围绕着什么是 Taro,为什么用 Taro,以及 Taro 如何使用(正确使用的姿势),还有 Taro 背后的一些设计思想来进行展开,让大家能够对 Taro 有个完整的认识。
01
Flutter For Web实践
Flutter For Web 已经发布一年多时间,它的发布意味着我们可以真正地使用一套代码、一套资源部署整个大前端系统(包括:iOS、Android、Web)。渠道研发组经过一段时间的探索,使用Flutter For Web技术开发了移动端可视化编程平台—Flutter乐高,在这里希望和大家分享下使用Flutter For Web实践过程和踩坑实践
01
配运基础数据缓存瘦身实践
在基础数据的常规能力当中,数据的存取是最基础也是最重要的能力,为了整体提高数据的读取能力,缓存技术在基础数据的场景中得到了广泛的使用,下面会重点展示一下配运组近期针对数据缓存做的瘦身实践。
自猿其说Tech
文章数
426
阅读量
2150053
作者其他文章
01
深入JDK中的Optional
01
Taro小程序跨端开发入门实战
01
Flutter For Web实践
01
配运基础数据缓存瘦身实践
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号