亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

drools規(guī)則動態(tài)化實踐解析

 更新時間:2023年02月07日 08:23:58   作者:京東云開發(fā)者  
這篇文章主要為大家介紹了drools規(guī)則動態(tài)化實踐解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

一 、 規(guī)則引擎業(yè)務應用背景

業(yè)務邏輯中經(jīng)常會有一些冗長的判斷,需要寫特別多的if else,或者一些判斷邏輯需要經(jīng)常修改。這部分邏輯如果以java代碼來實現(xiàn),會面臨代碼規(guī)??刂撇蛔?,經(jīng)常需要修改邏輯上線等多個弊端。這時候我們就需要集成規(guī)則引擎對這些判斷進行線上化的管理

二、規(guī)則引擎選型

目前開源的規(guī)則引擎也比較多,根據(jù)原有項目依賴以及短暫接觸過的規(guī)則引擎,我們著重了解了一下幾個

drools:

-社區(qū)活躍,持續(xù)更新

-使用廣泛

-復雜

-學習成本較高

github.com/kiegroup/dr…

easy-rule:

-簡單易學

-滿足使用訴求

-長時間未發(fā)布新版

github.com/j-easy/easy…

easycode:

-京東物流同事維護的平臺

-基于flowable dmn實現(xiàn)

-配置簡單直觀

-已有大量系統(tǒng)使用

總結:

  • 簡單配置型規(guī)則可以接入easycode,平臺提供配置頁面,通過jsf交互。
  • 復雜規(guī)則,需要動態(tài)生成規(guī)則,easycode目前還不支持。drools從流行度及活躍度考慮,都比easy-rule強,所以選擇drools。

三、 drools簡單示例

3.1 引入依賴

<dependency>
    <groupId>org.kie</groupId>
    <artifactId>kie-spring</artifactId>
    <version>${drools.version}</version>
</dependency>

3.2 寫drl文件

我們寫一個簡單的demo

規(guī)則為:

匹配一個sku對象

0<價格<=100 10積分

100<價格<=1000 100積分

1000<價格<=10000 1000積分

在resources文件夾下新增 rules/skupoints.drl 文件 內容如下

package com.example.droolsDemo
import com.example.droolsDemo.bean.Sku;

// 10積分
rule "10_points"
    when
        $p : Sku( price > 0 && price <= 100 )
    then
        $p.setPoints(10);
        System.out.println("Rule name is [" + drools.getRule().getName() + "]");
end

// 100積分
rule "100_points"
    when
        $p : Sku( price > 100 && price <= 1000 )
    then
        $p.setPoints(100);
        System.out.println("Rule name is [" + drools.getRule().getName() + "]");
end

// 1000積分
rule "1000_points"
    when
        $p : Sku( price > 1000 && price <= 10000 )
    then
        $p.setPoints(1000);
        System.out.println("Rule name is [" + drools.getRule().getName() + "]");
end

3.3 使用起來

    @Test
    public void testOneSku() {
        Resource resource = ResourceFactory.newClassPathResource("rules/skupoints.drl");
        KieHelper kieHelper = new KieHelper();
        kieHelper.addResource(resource);
        KieBase kieBase = kieHelper.build();
        KieSession kieSession = kieBase.newKieSession();
        Sku sku1 = new Sku();
        sku1.setPrice(10);
        kieSession.insert(sku1);
        int allRules = kieSession.fireAllRules();
        kieSession.dispose();
        System.out.println("sku1:" + JSONObject.toJSONString(sku1));
        System.out.println("allRules:" + allRules);
    }

    @Test
    public void testOneSku2() {
        Resource resource = ResourceFactory.newClassPathResource("rules/skupoints.drl");
        KieHelper kieHelper = new KieHelper();
        kieHelper.addResource(resource);
        KieBase kieBase = kieHelper.build();
        StatelessKieSession statelessKieSession = kieBase.newStatelessKieSession();
        Sku sku1 = new Sku();
        sku1.setPrice(10);
        statelessKieSession.execute(sku1);
        System.out.println("sku1:" + JSONObject.toJSONString(sku1));
    }

3.4 輸出

3.5 總結

如上,我們簡單使用drools,僅需要注意drl文件語法。根據(jù)drl文件生成規(guī)則的工作內存,通過KieSession或者StatelessKieSession與工作內存交互。整個流程并不復雜。注意 KieHelper僅是在演示中簡單使用,demo中包含使用bean來管理容器的方式,即便在簡單使用場景也不應通過 KieHelper來重復加載規(guī)則。

但是,這樣并不能滿足我們線上化判斷,或者頻繁更改規(guī)則的訴求。于是我們在實踐中需要對drools更高階的使用方式。

四、 drools動態(tài)化實踐

從以上簡單demo中我們可以看出,規(guī)則依賴drl文件存在。而業(yè)務實際使用中,需要動態(tài)對規(guī)則進行修改,無法直接使用drl文件。

以下是我了解過的四種動態(tài)的方案:

  • drt文件,創(chuàng)建模板,動態(tài)生成drl文件,也是我們目前所用的方式。
  • excel文件導入,實際上和模板文件類似,依然無法直接交給業(yè)務人員來使用。
  • 自己拼裝String,動態(tài)生成drl文件,網(wǎng)上大多數(shù)博文使用方式,過于原始。
  • api方式,drools的api方式復雜,使用需要對drl文件有足夠的了解。

最后介紹以下drools在項目中的實際使用方式

4.1 配置規(guī)則

我們的業(yè)務場景可以理解為多個緩沖池構成的一個網(wǎng)狀結構。

示例如下:

上圖中每個方塊為一個緩沖池,每條連線為一條從A緩沖池流向B緩沖池的規(guī)則。實際場景中緩沖池有數(shù)百個,絕大多數(shù)都有自己的規(guī)則,這些規(guī)則構成一張復雜的網(wǎng)絡。基于業(yè)務訴求,緩沖池的流向規(guī)則需要經(jīng)常變動,我們需要在業(yè)務中能動態(tài)改變這些連線的條件,或者改變連線。在這種情況下,如果使用靜態(tài)的drl文件來實現(xiàn)這些規(guī)則,需要數(shù)百規(guī)則文件,維護量大,且每次修改后使規(guī)則生效的代價較大。在此背景下,我們嘗試drools高階應用,既規(guī)則動態(tài)化實踐。

我們在創(chuàng)建緩沖池的頁面中加入了流向規(guī)則的創(chuàng)建環(huán)節(jié)。每個緩沖池維護自己的流向規(guī)則,即為自己的一根連線。如下圖:

4.2 動態(tài)生成drl

drt文件內容:

(實際業(yè)務模板中比這個復雜,有一定校驗及業(yè)務邏輯,此處做了簡化)

template header
// 模板需要使用的參數(shù)
id
cluePoolId
sourceList
cooperateTypeList
regionId
secondDepartmentId
battleId
outCluePoolId
amountCompareFlag
amount
salience

package rulePoolOut
// 全局對象
global java.util.List list;
global java.util.List stopIdList;
global java.util.List ruleIdList;
// 引入的java類
import com.example.drools.bean.ClueModel
import org.springframework.util.CollectionUtils
import org.apache.commons.lang3.StringUtils;
import java.lang.Long
template "CluePoolOut"
// 規(guī)則名稱
rule "clue_pool_@{cluePoolId}_@{id}"
//  參數(shù) 標識當前的規(guī)則是否不允許多次循環(huán)執(zhí)行
no-loop true
//  參數(shù) 優(yōu)先級
salience @{salience}
//  參數(shù) 規(guī)則組 本組規(guī)則只能有一個生效 
activation-group "out_@{cluePoolId}"
// 匹配的LHS
when
    $clue:ClueModel(cluePoolId == @{cluePoolId})
    ClueModel(CollectionUtils.isEmpty(@{sourceList}) || source memberOf @{sourceList})
    ClueModel(CollectionUtils.isEmpty(@{cooperateTypeList}) || cooperateType memberOf @{cooperateTypeList})
    ClueModel(secondDepart == @{secondDepartmentId})
    ClueModel(regionNo == @{regionId})
    ClueModel(battleId == @{battleId})
    ClueModel(null != estimateOrderCount && (Long.valueOf(estimateOrderCount) @{amountCompareFlag} Long.valueOf(@{amount})))
// 如果配置要執(zhí)行的RHS 支持java語法
then
    ruleIdList.add(@{id});
    $clue.setCluePoolId(Long.valueOf(@{outCluePoolId}));
    list.add(@{outCluePoolId});
    update($clue);
    }
end
end template

生成drl內容: 根據(jù)一個隊列及模板的路徑進行drl內容的生成

List<CrmCluePoolDistributeRuleBusinessBattleVO> ruleCenterVOS = new ArrayList<>();
CrmCluePoolDistributeRuleBusinessBattleVO vo = new CrmCluePoolDistributeRuleBusinessBattleVO();
vo.setCooperateTypeList(Lists.newArrayList(1, 2, 4));
vo.setAmountCompareFlag(">");
vo.setAmount(100L);
ruleCenterVOS.add(vo);
String drl = droolsManager.createDrlByTemplate(ruleCenterVOS, "rules/CluePoolOutRuleTemplate.drt");


    public String createDrlByTemplate(Collection<?> objects, String path) {
        ObjectDataCompiler compiler = new ObjectDataCompiler();
        try (InputStream dis = ResourceFactory.newClassPathResource(path, this.getClass()).getInputStream()) {
            return compiler.compile(objects, dis);
        } catch (IOException e) {
            log.error("創(chuàng)建drl文件失敗!", e);
        }
        return null;
    }

4.3 加載drl

上邊的簡單示例中,我們使用了KieHelper 來加載規(guī)則文件至工作內存中。實際上我們不可能在每次匹配中重新加載所有規(guī)則文件,所以我們可以單例的使用規(guī)則容器,通過以下方式或者也可以使用@Bean等方式來管理容器。

private final KieServices kieServices = KieServices.get();
// kie文件系統(tǒng),需要緩存,如果每次添加規(guī)則都是重新new一個的話,則可能出現(xiàn)問題。即之前加到文件系統(tǒng)中的規(guī)則沒有了
private final KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
// 需要全局唯一一個
private KieContainer kieContainer;

通過將內容寫入 kieFileSystem然后重新加載整個 kieBase即可重新加載規(guī)則,但是這種行為比較重,代價較大

也可以通過 kieBase新增一個文件來進行加載,代價小,但是同步各個實例的代價較大。

KnowledgeBaseImpl kieBase = (KnowledgeBaseImpl)kieContainer.getKieBase(kieBaseName);
KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
Resource resource = ResourceFactory.newReaderResource(new StringReader(ruleContent));
builder.add(resource,ResourceType.DRL);
if (builder.hasErrors()) {
    throw new RuntimeException("增加規(guī)則失敗!" + builder.getErrors().toString());
}
kieBase.addPackages(builder.getKnowledgePackages());

4.4 匹配

通過 StatelessKieSession與規(guī)則引擎交互

// 獲取一個鏈接
StatelessKieSession kieSession = droolsManager.getStatelessKieSession(RuleTemplateEnum.CLUE_POOL_OUT_RULE.getKieBaseName());
// 創(chuàng)建全局變量對象
List<Long> list = new ArrayList<>();
List<Long> stopIdList = Lists.newArrayList();
List<String> result = new ArrayList<>();
List<Long> ruleIdList = new ArrayList<>();
// 塞入全局變量
kieSession.setGlobal("ruleIdList", ruleIdList);
kieSession.setGlobal("list", list);
kieSession.setGlobal("stopIdList", stopIdList);
kieSession.setGlobal("result", result);
// 執(zhí)行規(guī)則
kieSession.execute(clueModel);

如果使用 KieSession則需要在使用完成后進行關閉

kieSession.insert(clueModel);
kieSession.fireAllRules();
kieSession.dispose();

在執(zhí)行規(guī)則的過程中可以加入各種監(jiān)聽器對過程中各種變化進行監(jiān)聽。篇幅原因交給各位去探索。

五、 總結

從上邊的流程中我們體驗了動態(tài)規(guī)則的創(chuàng)建以及使用。動態(tài)規(guī)則滿足了我們規(guī)則動態(tài)變化,規(guī)則統(tǒng)一管理的訴求。

我也總結了在這種使用方式下drools的幾個優(yōu)缺點。

優(yōu)點:

  • 規(guī)則動態(tài)化方便
  • 在工作內存中匹配規(guī)則性能好
  • 幾乎可以滿足所有的規(guī)則需求
  • 內置方法豐富完善

缺點:

  • 分布式一致性需要自行處理
  • 需要研發(fā)了解drl語法
  • 學習曲線陡峭
  • 匹配過程監(jiān)控手段需要自行實現(xiàn)

以上就是drools規(guī)則動態(tài)化實踐解析的詳細內容,更多關于drools規(guī)則動態(tài)化的資料請關注腳本之家其它相關文章!

相關文章

  • 不使用myeclipse注冊機得到myeclipse注冊碼的方法(myeclipse序列號)

    不使用myeclipse注冊機得到myeclipse注冊碼的方法(myeclipse序列號)

    本文為大家介紹不使用myeclipse注冊機就能得到myeclipse注冊碼(序列號)的方法, 運行下面的JAVA代碼就可以了
    2014-01-01
  • Spring Boot全局統(tǒng)一異常處理器

    Spring Boot全局統(tǒng)一異常處理器

    軟件開發(fā)springboot項目過程中,不僅有大量的冗余代碼,而且還影響代碼的可讀性.這樣就需要定義個全局統(tǒng)一異常處理器,以便業(yè)務層再也不必處理異常.文中有非常詳細的代碼示例,需要的朋友可以參考下
    2021-05-05
  • Spring中@EnableScheduling注解的工作原理詳解

    Spring中@EnableScheduling注解的工作原理詳解

    這篇文章主要介紹了Spring中@EnableScheduling注解的工作原理詳解,@EnableScheduling是 Spring Framework 提供的一個注解,用于啟用Spring的定時任務(Scheduling)功能,需要的朋友可以參考下
    2024-01-01
  • java讀取word文檔,提取標題和內容的實例

    java讀取word文檔,提取標題和內容的實例

    這篇文章主要介紹了java讀取word文檔,提取標題和內容的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Jenkins任務批量修改的技巧分享

    Jenkins任務批量修改的技巧分享

    這篇文章主要給大家介紹了關于Jenkins任務批量修改的一些技巧,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-03-03
  • spring boot+vue 的前后端分離與合并方案實例詳解

    spring boot+vue 的前后端分離與合并方案實例詳解

    這篇文章主要介紹了spring boot+vue 的前后端分離與合并方案實例詳解,需要的朋友可以參考下
    2017-11-11
  • 詳解Java停止線程的四種方法

    詳解Java停止線程的四種方法

    如何停止java的線程一直是一個困惱我們開發(fā)多線程程序的一個問題嗎,本文主要介紹了詳解Java停止線程的四種方法,感興趣的可以了解一下
    2021-05-05
  • SpringSecurity數(shù)據(jù)庫進行認證和授權的使用

    SpringSecurity數(shù)據(jù)庫進行認證和授權的使用

    本文主要介紹了用戶的賬號、密碼以及角色信息在數(shù)據(jù)庫中的認證和授權,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Spring?Security?中多個身份驗證的示例代碼

    Spring?Security?中多個身份驗證的示例代碼

    這篇文章主要介紹了Spring?Security?中多個身份驗證的示例代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • Spring Boot攔截器和過濾器實例解析

    Spring Boot攔截器和過濾器實例解析

    這篇文章主要介紹了Spring Boot攔截器和過濾器實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01

最新評論