16.客戶端服務器(qì)配置

概述

URule Pro支持三種運行(xíng)模式,分别是嵌入模式、分布式計(jì)算(suàn)模式以及獨立服務模式,實際使用時(shí),根據項目情況三選一即可(kě)。

所謂的嵌入模式就是将URule嵌入到目标應用當中運行(xíng),這種模式的特點部署起來(lái)簡單、方便,便于系統開(kāi)發與調試; 分布式計(jì)算(suàn)模式就是把計(jì)算(suàn)分布到各個(gè)應用當中,規則服務器(qì)隻負責規則的構建、打包與測試,具體(tǐ)的規則計(jì)算(suàn)發生(shēng)在計(jì)算(suàn)應用當中,規則服務器(qì)通(tōng)過Http協議将知識包推送到各個(gè)計(jì)算(suàn)應用,分布式計(jì)算(suàn)模式适用于單個(gè)服務器(qì)不強,規則計(jì)算(suàn)時(shí)需要的輸入數(shù)據結構複雜的情況。

最後一種就是獨立服務模式,這種模式也是傳統規則引擎采用的模式,那(nà)就是規則服務器(qì)通(tōng)過暴露Restful服務來(lái)接收各種類型規則計(jì)算(suàn)請(qǐng)求,請(qǐng)求把輸入數(shù)據以JSON格式提供,在一台服務器(qì)上(shàng)完成所有(yǒu)類型的規則計(jì)算(suàn),計(jì)算(suàn)完成後再把輸出數(shù)據以JSON格式返回, 在第22小(xiǎo)節知識包Restful服務暴露與調用中詳細介紹了這種模式的配置及使用方式,本小(xiǎo)節将隻對嵌入模式和(hé)分布式計(jì)算(suàn)模式兩種類型結構進行(xíng)介紹。

在之前介紹的內(nèi)容當中,安裝與配置一節介紹的項目創建配置方式就是采用的嵌入模式,在嵌入式模式下URule Pro相關Jar包與業務應用一起打包,作(zuò)為(wèi)一個(gè)應用來(lái)進行(xíng)部署,這種模式結構比較簡單,開(kāi)發、部署起來(lái)都比較容易。

再來(lái)看看分布式計(jì)算(suàn)模式示意圖:

在分布式計(jì)算(suàn)模式下,包含URule Pro Console模塊的應用被部署成一個(gè)獨立的Server,在這個(gè)Server上(shàng)創建規則項目,在項目中根據業務需求添加決策集、決策表、交叉決策表、決策樹(shù)、評分卡、複雜評分卡、決策流等,再把這些(xiē)文件打包到知識包中,最後通(tōng)過HTTP協議暴露給各個(gè)客戶端業務系統使用。

分布式計(jì)算(suàn)模式下客戶端獲取服務端知識包的方式:

在分布式計(jì)算(suàn)模式下,URule Server上(shàng)給客戶端提供的是若幹個(gè)已經構建好的知識包對象,當有(yǒu)客戶端需要進行(xíng)規則計(jì)算(suàn)時(shí),它會(huì)檢查當前客戶端中配置的“urule.knowledgeUpdateCycle”屬性值,如果為(wèi)0,那(nà)麽就直接請(qǐng)求URule Server獲取指知識包;如果為(wèi)1,那(nà)麽它會(huì)首先檢查客戶端本地緩存當中是否存在指定的知識包,如果存在,就取本地緩存中的,如果不存在,則到URule Server下請(qǐng)求指定的知識包,然後将請(qǐng)求到的知識包緩存到客戶端內(nèi)存中,這樣下次就不再到URule Server上(shàng)下載;如果“urule.knowledgeUpdateCycle”屬性值大(dà)于1,那(nà)麽客戶端會(huì)首先檢查本地緩存中是否存在指定的知識包,如果存在,那(nà)麽就拿(ná)當前時(shí)間(jiān)與本地緩存中的知識包的時(shí)間(jiān)戳進行(xíng)比較,如果小(xiǎo)于“urule.knowledgeUpdateCycle”屬性值,那(nà)麽就直接取這個(gè)知識包,如果大(dà)于它,那(nà)麽就到URule Server上(shàng)通(tōng)過時(shí)間(jiān)戳檢查當前知識包有(yǒu)沒有(yǒu)更新,如果有(yǒu)更新則取到客戶端,同時(shí)更新客戶端緩存裏對應的知識包;如果沒有(yǒu)更新,那(nà)麽就直接采用當前客戶端緩存裏的知識包。。

搭建Server應用

搭建URule Server應用的與安裝與配置一節中介紹的完全相同,就是在一個(gè)普通(tōng)的java web應用中将URule Pro Console模塊和(hé)URule Pro Core添加進去。需要注意的是,在URule Server應用搭建好了之後,要保證“/urule/loadknowledge”這個(gè)URL在可(kě)以匿名訪問,比如輸入類似下面的地址,看看應用會(huì)有(yǒu)什麽樣的響應。

http://localhost:8080/urule-server/urule/loadknowledge

在系統未登錄的情況下,訪問上(shàng)述URL看到的不是一個(gè)登錄頁面,那(nà)麽就說明(míng)“/urule/loadknowledge”這個(gè)URL在可(kě)以匿名訪問,是OK的。

如果出現我們應用中的登錄界面之類,那(nà)就說明(míng)“/urule/loadknowledge”這個(gè)URL被我們自己系統內(nèi)部的權限模塊給攔截了,需要我們在系統中對內(nèi)部的權限進行(xíng)配置,使得(de)“/urule/loadknowledge”URL在可(kě)以匿名訪問。做(zuò)好這個(gè)工作(zuò),那(nà)麽URule Server的搭建工作(zuò)就完成了,下面我們看看如果配置客戶端應用。

配置客戶端應用

配置客戶端應用,首先要解決的是如果将URule Pro客戶端所需要的jar包添加到項目中,這裏我們分maven項目以及非maven項目分别進行(xíng)討(tǎo)論。

maven項目配置

如果當前客戶端是基于maven的項目,那(nà)麽我們需要在其pom.xml中添加以下依賴:

<dependency>
    <groupId>com.bstek.urule</groupId>
    <artifactId>urule-core-pro</artifactId>
    <version>3.0.3</version>
</dependency>

可(kě)以看到,在客戶端當中就不再需要urule-console-pro模塊了,隻需要一個(gè)urule-core-pro模塊即可(kě)。

上(shàng)面的maven依賴中,我們使用的是3.0.3版本,實際使用時(shí),可(kě)以在網頁中打開(kāi)https://search.maven.org/,查詢“urule-core-pro”關鍵字,找到最新的urule-core-pro的版本信息,以确定在依賴中version位置要輸入的版本号信息。

到這裏,pom的配置就完成了,我們再來(lái)看看一個(gè)标準的非maven的Web項目如何配置成URule Pro客戶端。

非maven項目配置

如果是一個(gè)非maven普通(tōng)的java web項目,添加URule Pro客戶端就是将urule-core-pro的jar包及其依賴的第三方jar包放到客戶端應用的/WEB-INF/lib目錄下即可(kě),urule-core-pro的jar包我們可(kě)以到https://search.maven.org/上(shàng)下載最新的urule-core-pro-2.x的jar包,對于依賴的第三方jar包,可(kě)以點擊此處下載。

加載spring配置文件

URule Pro客戶端所需要的jar包添加到客戶端項目中後,接下來(lái)我們還(hái)需要加載urule-core-pro模塊中的spring配置文件。urule-core-pro模塊中的spring配置文件位于classpath根下,名為(wèi)urule-core-context.xml。

如果我們的客戶端項目沒有(yǒu)采用spring框架,那(nà)麽可(kě)以在web.xml中添加如下所示Listener來(lái)加載urule-core模塊中的spring配置文件:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:urule-core-context.xml</param-value>
</context-param>

如果我們的項目也采用了spring框架,那(nà)麽隻需要打開(kāi)項目中任意一個(gè)spring配置文件,在其中添加如下配置即可(kě):

<import resource="classpath:urule-core-context.xml"/>

這樣urule-core-pro的spring配置文件的加載配置就完成了。

配置服務器(qì)地址

對于URule Pro客戶端應用來(lái)說,在進行(xíng)規則計(jì)算(suàn)時(shí),如果客戶端本地緩存沒有(yǒu)相應的知識包,那(nà)麽它會(huì)到URule Server上(shàng)請(qǐng)求對應的知識包,要給URule Pro客戶端應用配置對應的URule Server地址,我們需要添加一個(gè)properties文件,比如在項目的WEB-INF目錄下新建一個(gè)名為(wèi)configure的properties文件,然後在我們項目中任意一個(gè)spring配置文件中添加如下配置加載這個(gè)properties文件:

<bean parent="urule.props">
    <property name="location">
        <value>/WEB-INF/configure.properties</value>
    </property>
</bean>

打開(kāi)這個(gè)configure.properties文件,在其中添加一個(gè)名為(wèi)“urule.resporityServerUrl”屬性,比如 urule.resporityServerUrl=http://192.168.18.11:8080/urule-server , 就表明(míng)我們為(wèi)當前URule客戶端應用配置的URule Server為(wèi)“http://192.168.18.11:8080/urule-server”,這樣在進行(xíng)規則計(jì)算(suàn)時(shí),如果客戶端本地緩存沒有(yǒu)相應的知識包,那(nà)麽它會(huì)到“http://192.168.18.11:8080/urule-server”上(shàng)請(qǐng)求對應的知識包。

從2.1.1版本開(kāi)始,urule-pro提供了動态加載Jar包及Spring配置文件功能,具體(tǐ)見21.Spring Bean及Java類的熱部署描述,如果我們使用的是urule-pro-2.1.1及以上(shàng)版本, 那(nà)麽在采用客戶端服務器(qì)模式配置應用時(shí),客戶端配置了“urule.resporityServerUrl”屬性後,客戶端在啓動時(shí)會(huì)自動到服務端檢查是否有(yǒu)新的動态Jar文件信息需要加載,如果有(yǒu)則下載到客戶端并加載, 所以這時(shí)服務端的“urule/dynamic/checkLatestJarsDir”和(hé)“urule/dynamic/loadDynamicJars”這兩個(gè)URL要保證匿名可(kě)訪問,否則客戶端啓動時(shí)會(huì)産生(shēng)錯誤。

到這裏,URule Pro客戶端的配置就全部完成了,通(tōng)過指定urule.resporityServerUrl屬性值,我們的客戶端無論是标準的Java Web應用還(hái)是普通(tōng)的Java應用,都可(kě)以與URule Server連接,從而在運行(xíng)時(shí)獲取到相應的知識包。

但(dàn)是,如果我們的客戶端應用是标準的Java Web應用,那(nà)麽除了可(kě)以通(tōng)過urule.resporityServerUrl屬性指定URule Server地址,從而主動獲取知識包外,還(hái)可(kě)以通(tōng)過配置一個(gè)Servlet被動接收URule Server推送過來(lái)的知識包,這樣模式,相比主動獲取知識包方式要高(gāo)效的多(duō),同時(shí)還(hái)可(kě)以時(shí)刻與Server上(shàng)的知識包保持同步。

下面就來(lái)看看如何給一個(gè)類型為(wèi)标準Java Web應用的客戶端配置接收服務端推送過來(lái)知識包的Servlet。

配置web.xml

在之前內(nèi)容中我們就提過,URule Pro的客戶端即可(kě)以是标準的Java Web應用,也可(kě)以是普通(tōng)的Java應用。如果是普通(tōng)Java應用,那(nà)麽上(shàng)面的那(nà)麽配置就可(kě)以了;如果是标準的Java Web應用,那(nà)麽我們還(hái)可(kě)以做(zuò)些(xiē)配置,使得(de)其以主動接收來(lái)自URule Server上(shàng)推送過來(lái)的最新的知識包。

對于URule Server來(lái)說,如果在規則項目中配置了URule的客戶端地址,那(nà)麽在知識包發布時(shí)會(huì)自動推送到這些(xiē)客戶端。所以我們的URule Pro客戶端如果是個(gè)标準的Java Web應用,那(nà)麽可(kě)以配置一個(gè)可(kě)以接收URule Server推送的知識包的Servlet。

打開(kāi)項目的web.xml,在其中添加如下servlet配置:

<servlet>
    <servlet-name>uruleClientServlet</servlet-name>
    <servlet-class>com.bstek.urule.KnowledgePackageReceiverServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>uruleClientServlet</servlet-name>
    <url-pattern>/knowledgepackagereceiver</url-pattern>
</servlet-mapping>

在上(shàng)面的servlet配置中,url-pattern項的“/knowledgepackagereceiver”值是固定的,不能修改為(wèi)其它值,否則将無法收到URule Server上(shàng)推送過來(lái)的知識包。 同時(shí),客戶端中的這個(gè)用于接收知識包推送的Servlet還(hái)要保證其可(kě)以匿名訪問,也就是客戶端中如果被權限框架包裹,那(nà)麽要保證“/knowledgepackagereceiver”這個(gè)URL在不登錄的情況下就可(kě)以訪問, 否則服務端将無法把知識包推送到目标客戶端。

要實現推送功能,除了要配置對應Java Web客戶端上(shàng)的Servlet,還(hái)需要在URule Server上(shàng)對可(kě)以接收推送的客戶端進行(xíng)定義。

URule Server上(shàng)客戶端配置

打開(kāi)URule Pro的控制(zhì)台,在規則項目中點擊右鍵,在彈出的菜單中選擇“配置接收推送客戶端”,就可(kě)以打開(kāi)客戶端配置頁面,如下圖:

我們可(kě)以添中多(duō)個(gè)客戶端,這樣在當前項目發布知識包時(shí)就可(kě)以自動推送到這裏的客戶端上(shàng),如下圖:

配置完成後,點擊當前項目的“知識包”節點,選擇任意一個(gè)知識包,在知識包操作(zuò)菜單中點擊“發布新知識包”菜單項,知識包發布成功後會(huì)看到如下圖所示的提示:

點擊“确定”,系統會(huì)嘗試向這些(xiē)客戶端推送當前發布的知識包對象,如果這些(xiē)客戶端是存在的,就可(kě)以發布成功,這樣對應的客戶端本地緩存中就會(huì)存儲這個(gè)發布的知識包對象。

實際使用當中,如果希望向客戶端推送某個(gè)已發布的知識包版本,我們也可(kě)以點擊知識包操作(zuò)菜單中“已發布的知識包”菜單項,在彈出的窗口當中,可(kě)以看到所有(yǒu)已經發布的知識包列表,如下圖所示:

如果需要将某個(gè)知識包推送到客戶端,那(nà)麽可(kě)以點擊上(shàng)圖中紅框內(nèi)按鈕,這樣就可(kě)以将當前版本知識包推送到客戶端當中。

客戶端動态配置

實際使用時(shí),我們可(kě)能會(huì)在諸如docker之類的容器(qì)中部署客戶端應用,在這種情況下,客戶端的IP地址不是固定的,此時(shí)要在服務端指定客戶地址的話(huà),采用上(shàng)面的方法就行(xíng)不通(tōng)了。 為(wèi)了兼容這種客戶端IP地址動态變化的場(chǎng)景,URule Pro當中還(hái)提供了一個(gè)名為(wèi)ClientProvider接口,通(tōng)過實現這個(gè)接口來(lái)動态指定客戶端IP地址,ClientProvider接口類源碼如下:

package com.bstek.urule.console.repository;

import java.util.List;

/**
 * @author Jacky.gao
 * @since 2019年12月29日
 */
public interface ClientProvider {
    /**
     * @param project 規則項目名稱
     * @param all 是否加載所有(yǒu)的客戶端信息,如果為(wèi)true,則包括禁用的客戶端信息
     * @return 返回客戶端地址的集合
     */
    List<ClientConfig> loadClients(String project,boolean all);
}

實現了ClientProvider接口後,隻需要将實現類配置到Spring上(shàng)下文當中,使之成為(wèi)一個(gè)标準的Spring Bean即可(kě),這樣引擎在獲取配置的客戶端信息時(shí)就會(huì)嘗試從這個(gè)實現類中獲取。 下面是我們編寫的一個(gè)測試用的ClientProvider接口實現類:

package test;

import java.util.ArrayList;
import java.util.List;

import com.bstek.urule.console.repository.ClientConfig;
import com.bstek.urule.console.repository.ClientProvider;

public class TestClientProvider implements ClientProvider {

    @Override
    public List<ClientConfig> loadClients(String project, boolean all) {
        List<ClientConfig> list=new ArrayList<ClientConfig>();
        ClientConfig cc=new ClientConfig();
        list.add(cc);
        cc.setName("測試");
        cc.setClient("www.baidu.com");
        cc.setEnabled(true);
        cc.setProject("保險行(xíng)業示例項目");
        return list;
    }
}

将該實現類配置到Spring當中,重啓應用,再次打開(kāi)項目中“配置接收推送客戶端”頁面,則會(huì)看到如下圖所示效果:

可(kě)以看到當前頁面會(huì)把實現類中配置的客戶端信息展示出來(lái),同時(shí)該頁面也不再提供客戶端信息的編輯功能。

前面我們介紹了在URule Pro客戶端中配置“urule.knowledgeUpdateCycle”屬性的含義及目的,一旦我們在URule Server中配置了客戶端地址,那(nà)麽知識包每次發布都會(huì)被推送到這些(xiē)客戶端。這樣在生(shēng)産環境下,對于客戶端來(lái)說,“urule.knowledgeUpdateCycle”屬性值隻要設置成1即可(kě),也就是每次都在客戶端本地緩存中查找目标知識包是否存在,如果存在直接使用。如果知識包有(yǒu)更新,URule Server會(huì)動推送到目标客戶端,對于客戶端來(lái)說直接從本地緩存中就可(kě)以取到最新的知識包,這樣可(kě)以剔除所有(yǒu)不必要的客戶端與服務端的交互,節省網絡資源,同時(shí)可(kě)以大(dà)幅提高(gāo)客戶端規則計(jì)算(suàn)性能。

我們在對URule Pro進行(xíng)性能測試時(shí),一定要将“urule.knowledgeUpdateCycle”屬性值隻要設置成1,因為(wèi)“urule.knowledgeUpdateCycle”屬性值默認為(wèi)0,所以每次執行(xíng)規則都會(huì)編譯一次規則包,這樣會(huì)帶來(lái)很(hěn)差的測試結果,所以這點非常關鍵; 在客戶端中,将“urule.knowledgeUpdateCycle”設置成1後,檢驗該屬性是否生(shēng)效最好的方法是在客戶端調用服務端知識包時(shí)觀察控制(zhì)台是否有(yǒu)類似“Load knowledgepackage [ packageId ] from remote...”這樣的字符輸出,如果有(yǒu)類似輸出,則說明(míng)urule.knowledgeUpdateCycle=1未生(shēng)效, 我們需要進一步檢查配置,找到未生(shēng)效的原因。 同時(shí),名為(wèi)"urule.debug"的屬性也會(huì)對性能産生(shēng)一點影(yǐng)響,這個(gè)屬性值默認為(wèi)true,表示允許進行(xíng)調試信息輸出,這樣對于性能測試來(lái)說無疑會(huì)造成影(yǐng)響,所以在性能測試或生(shēng)産環境中建議将“urule.debug”屬性設置為(wèi)false,這樣可(kě)以減少(shǎo)不必要的調試信息輸出,可(kě)顯著提升性能。

results matching ""

    No results matching ""