JBoss Drools中提供了一個類KieScanner,可以支持從Maven存儲庫動態的加載並更新規則。官方給出的例子沒有很好的證明這一能力,筆者經過幾天研究,成功實驗出瞭如何達到動態更新的效果,整理出來供大家參考。相關的源代碼可以從Gitee下載。
程序結構和運行目標
如圖所示,演示項目共包含四個項目:
- my-dynamic-rule: 父項目
- my-kjar: 一個kjar項目,其中包含了kmodule.xml文件和Drools規則.drl文件
- my-dynamic-engine: 一個Spring Boot項目,規則引擎運行於此,對外提供Rest服務
- my-model: 一個簡單Java項目,包含my-kjar和my-dynamic-engine項目依賴的模型POJO
規則引擎服務my-dynamic-engine中並不包含規則,服務啓動時,將從Maven存儲庫中拉取my-kjar項目,並加載其中的規則。啓動以後,規則引擎服務將不停的監視Maven存儲庫中的my-kjar是否更新,如果更新則更新其中新的規則,規則引起服務本身不需重新啓動。
my-kjar項目
my-kjar項目是一個kjar項目,其中包含了kmodule.xml文件和Drools規則.drl文件。kjar項目是指引入了kie-maven-plugin插件,並指定打包爲kjar,在打包的過程中,插件會校驗以drl定義的規則是否可以正常編譯。設置kjar項目的方法如下:
<packaging>kjar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.kie</groupId>
<artifactId>kie-maven-plugin</artifactId>
<version>7.6.0.Final</version>
<extensions>true</extensions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.kie</groupId>
<artifactId>
kie-maven-plugin
</artifactId>
<versionRange>
[7.6.0.Final,)
</versionRange>
<goals>
<goal>generateModel</goal>
<goal>build</goal>
<goal>injectreactive</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
my-dynamic-engine項目
my-dynamic-engine是一個Spring Boot項目,可以動態加載規則的關鍵在於,在KieContainter容器上註冊了一個KieScanner:
@PostConstruct
public void setUp() {
KieServices ks = KieServices.Factory.get();
ReleaseId releaseId = ks.newReleaseId("my-group", "my-kjar", "LATEST");
kContainer = ks.newKieContainer(releaseId);
KieScanner kScanner = ks.newKieScanner(kContainer);
// Start the KieScanner polling the Maven repository every 10 seconds
kScanner.start(10000L);
}
程序運行
1. 將my-dynamic-rule, my-model, my-kjar項目安裝到Maven本地存儲庫
2. 使用mvn clean package打包my-dynamic-engine項目,並啓動
3. 在瀏覽器中訪問http://localhost:8080/dynamic-rule,可見規則引擎執行的結果:
4. 修改my-kjar項目中的Hal1.drl,如
5. 重新執行mvn install安裝my-kjar項目,從規則引擎日誌中可見規則已經更新
6. 在瀏覽器中訪問http://localhost:8080/dynamic-rule,可見規則引擎執行的結果已經更新:
使用遠程Maven存儲庫
以上的例子適合於開發環境,如果運行於運行時環境,則需要配置連接遠程Maven存儲庫。Kie-ci依賴在規則引擎中引入了內嵌的Maven客戶端,啓動時會合並以下三個位置的Maven settings.xml配置文件:
- The Maven install: $M2_HOME/conf/settings.xml (配置M2_HOME爲環境變量)
- A user’s install: ${user.home}/.m2/settings.xml
- Folder location specified by the system property kie.maven.settings.custom
作者已經使用Nexus測試了遠程Maven存儲庫,遇到一個問題,受Maven本地緩存的影響,更新遠程Maven存儲庫中的kjar以後,需要手動刪除本地kjar所在的目錄。嘗試配置了updatePolicy,但還是不能自動抓取遠程最新的kjar。
參考資料
https://docs.jboss.org/drools/release/7.6.0.Final/drools-docs/html_single/index.html#_kiescanner