從2.1.1版本開(kāi)始,在URule Pro中提供了Spring Bean及Java類的熱部署功能。利用該功能,打開(kāi)URule Pro控制臺(tái)即可將需要熱部署的Spring Bean及相關(guān)Java類文件實(shí)時(shí)部署到正在運(yùn)行的服務(wù)器中。 對(duì)于采用客戶端服務(wù)器模式運(yùn)行的URule Pro應(yīng)用,只需要在服務(wù)端部署好需要的Spring Bean及相關(guān)Java類文件,客戶端會(huì)自動(dòng)獲取這些已部署的Spring Bean及相關(guān)Java類文件信息,并對(duì)其進(jìn)行執(zhí)加載。
有了這個(gè)功能,URule Pro中無(wú)論是用戶自定義的動(dòng)作庫(kù)還是內(nèi)置動(dòng)作庫(kù)相關(guān)的Spring Bean及Java類,都可以在服務(wù)器運(yùn)行情況下,實(shí)時(shí)動(dòng)態(tài)部署。
打開(kāi)URule Pro控制臺(tái),點(diǎn)擊左側(cè)項(xiàng)目列表上方按鈕,即可打開(kāi)動(dòng)態(tài)部署Jar文件的配置頁(yè)面,如下圖所示:
在上面的部署頁(yè)面中,可以點(diǎn)擊“添加”按鈕添加一個(gè)新的部署項(xiàng),接下來(lái)點(diǎn)擊具體部署項(xiàng)“操作”列中的“編輯”按鈕,即可在彈出的窗口中添加這個(gè)部署項(xiàng)中涉及到的Jar文件信息,如下圖所示:
在這個(gè)彈出的窗口中,可以把所有相關(guān)的Jar文件通過(guò)窗口里選擇文件按鈕上傳到知識(shí)庫(kù)中,完成之后點(diǎn)擊頁(yè)面工具欄上“部署”,即可將所有部署項(xiàng)中上傳的Jar文件動(dòng)態(tài)部署到當(dāng)前項(xiàng)目中;如果當(dāng)前項(xiàng)目被當(dāng)前URule Server使用,同時(shí)又在各個(gè)項(xiàng)目里配置了URule的客戶端地址, 那么在Server上部署完成后,系統(tǒng)會(huì)提示我們要不要將這些動(dòng)態(tài)的Jar文件推送到URule客戶端,如果選擇是,那么這些客戶端立即接收到這些Jar文件并動(dòng)態(tài)加載,如下圖所示:
在URule Server的規(guī)則項(xiàng)目里配置客戶端地址,可以參見(jiàn)客戶端服務(wù)器配置介紹,這里不再贅述。
從部署方式上了解到,我們只需要將需要熱部署的Jar包上傳到系統(tǒng)即可,如果其中要加載Spring Bean,那么還需要定義好Spring的xml配置文件放在Jar包中一并上傳,下面來(lái)舉例說(shuō)明Spring配置文件及Jar文件打包方式。
假如我們需要部署下面這個(gè)Java類文件,內(nèi)容如下:
package test;
/**
* @author Jacky.gao
* @since 2019年1月11日
*/
public class BusinessTest {
public String hello(String name) {
System.out.println(new OtherBusiness().getENV());
return "Hello, "+name;
}
}
從上面的代碼中可以看出,這里的hello方法引用了OtherBusiness類中的getENV方法,OtherBusiness類源碼如下:
package test;
/**
* @author Jacky.gao
* @since 2019年1月11日
*/
public class OtherBusiness {
public String getENV() {
return "環(huán)境 is OK...";
}
}
可以看到getENV方法非常簡(jiǎn)單,只是返回一個(gè)字符串而已,對(duì)于BusinessTest類,我們希望它成為一個(gè)標(biāo)準(zhǔn)的Spring Bean,所以還要添加一個(gè)Spring的xml配置文件,內(nèi)容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
">
<bean id="dybean" class="test.BusinessTest"></bean>
</beans>
在上面這段xml配置中,test.BusinessTest類被配置成為一個(gè)標(biāo)準(zhǔn)的Spring Bean,Bean的ID為dybean。到這里Java類的編寫(xiě)及Spring Bean的xml配置工作就完成了,接下來(lái)就需要將它們打包Jar并上傳到URule中實(shí)際熱部署。
為了演示Java類引用多個(gè)不同Jar包中其它類庫(kù)的情形,這里我們把BusinessTest類和OtherBusiness類打成兩個(gè)Jar文件,分別是main.jar和slave.jar,至于Spring Bean的xml配置文件放在兩個(gè)Jar文件中任何一個(gè)中都可以,只是xml的名稱必須是urule-spring-context.xml, 且這個(gè)名為urule-spring-context.xml的Spring配置文件必須放在Jar文件的根下,這里我們把這個(gè)urule-spring-context.xml文件打包在main.jar文件當(dāng)中。
打包好的main.jar文件結(jié)構(gòu)如下圖所示:
打包好的slave.jar文件結(jié)構(gòu)如下圖所示:
上面的兩個(gè)Jar文件中,BusinessTest類和OtherBusiness類都位于test這個(gè)package下,所以截圖中只看到test這個(gè)package。
對(duì)于URule Pro來(lái)說(shuō),每個(gè)Jar文件中都可以包含一個(gè)名為urule-spring-context.xml的Spring的xml配置文件,如果包含每個(gè)文件中的Spring配置文件都會(huì)被解析并加載;
當(dāng)然也可以都不包含,這樣熱部署時(shí)引擎只會(huì)加載Jar包中的類。
當(dāng)我們點(diǎn)擊“態(tài)部署Jar文件的配置頁(yè)面”上的部署按鈕時(shí),系統(tǒng)會(huì)嘗試取到知識(shí)庫(kù)里所有已上傳的Jar文件,然后通過(guò)System.getProperty("java.io.tmpdir")取到當(dāng)前JVM應(yīng)用的臨時(shí)目錄,同時(shí)在其下創(chuàng)建名為urule-jars的目錄, 最后取當(dāng)前系統(tǒng)日期作為Jar文件的最終存儲(chǔ)目錄。
每次點(diǎn)擊“部署”按鈕時(shí),系統(tǒng)都會(huì)嘗試刪除原來(lái)的由系統(tǒng)日期生成的子目錄,再根據(jù)當(dāng)前日期重新創(chuàng)建子目錄,再把所有的Jar文件放在這個(gè)目錄下。
在臨時(shí)目錄中生成好所有的已上傳的Jar文件后,接下來(lái)系統(tǒng)會(huì)嘗試加載這個(gè)目錄下的所有Jar文件,如果這些Jar文件根下包含名為urule-spring-context.xml的Spring配置文件,系統(tǒng)也會(huì)將這個(gè)文件加載到Spring上下文中。 在實(shí)際使用時(shí),如果運(yùn)行URule Pro的應(yīng)用采用集群部署,并且集群實(shí)例運(yùn)行在同一個(gè)JDK下,這樣多個(gè)實(shí)例運(yùn)行時(shí)通過(guò)System.getProperty("java.io.tmpdir")取到當(dāng)前JVM應(yīng)用采用的臨時(shí)目錄可能是同一個(gè)目錄,不同的實(shí)例操作同一個(gè)目錄可能會(huì)存在問(wèn)題, 為解決這種因集群而導(dǎo)致的問(wèn)題,URule Pro允許為每個(gè)實(shí)例設(shè)置一個(gè)名為urule.instance.id的JVM參數(shù),要保證每個(gè)實(shí)例下該參數(shù)值不同, URule Pro在啟動(dòng)時(shí)就會(huì)嘗試采用這個(gè)JVM參數(shù)值作為通過(guò)System.getProperty("java.io.tmpdir")取到當(dāng)前臨時(shí)目錄下的子目錄名稱,這樣每個(gè)實(shí)例只會(huì)在這個(gè)子目錄下進(jìn)行創(chuàng)建存儲(chǔ)Jar文件的目錄,通過(guò)這種方式就可以避免在一臺(tái)物理機(jī)器上搭建多集群實(shí)例 而產(chǎn)生的問(wèn)題。
實(shí)際使用中,如果我們不想讓引擎通過(guò)System.getProperty("java.io.tmpdir")這種方式,取到的臨時(shí)目錄來(lái)作為動(dòng)態(tài)Jar文件的存儲(chǔ)父目錄,那么可以在Spring的Properties文件中添加一個(gè)名為urule.dynamicJarsPath的屬性來(lái)手工指定一個(gè)用于存儲(chǔ)動(dòng)態(tài)Jar文件的 父目錄,需要注意的是通過(guò)urule.dynamicJarsPath屬性指定的目錄一定要存在,否則啟動(dòng)時(shí)會(huì)產(chǎn)生錯(cuò)誤。
對(duì)于采用客戶端服務(wù)器模式運(yùn)行的應(yīng)用來(lái)說(shuō),如果客戶端是一個(gè)Java Web應(yīng)用,那么只需要按照客戶端服務(wù)器配置中介紹的在客戶端中配置好接收服務(wù)端推送過(guò)來(lái)的知識(shí)庫(kù)的Servlet即可,這樣服務(wù)端動(dòng)態(tài)Jar部署時(shí)會(huì)提示 是否推送到客戶端,如果選是,那么這些動(dòng)態(tài)Jar文件會(huì)直接推送到目標(biāo)客戶端,客戶端收到后也會(huì)按照上述方式加載這些Jar文件及其中可能存在的名為urule-spring-context.xml的Spring配置文件。
和知識(shí)包的客戶端一樣,客戶端也可以主動(dòng)檢查服務(wù)端是否存在動(dòng)態(tài)Jar文件,檢查方式也是在客戶端上配置“urule.resporityServerUrl”屬性值,所以從2.1.1版本開(kāi)始,客戶端中配置好“urule.resporityServerUrl”屬性值后,客戶端應(yīng)用除了會(huì)利用這個(gè)URL到服務(wù)端下載規(guī)則包, 還會(huì)在啟動(dòng)時(shí)利用這個(gè)URL檢查服務(wù)端是否存在動(dòng)態(tài)加載的Jar文件,如果有則下載到客戶端并加載;這時(shí)服務(wù)端的“urule/dynamic/checkLatestJarsDir”和“urule/dynamic/loadDynamicJars”這兩個(gè)URL要保證匿名可訪問(wèn),否則客戶端啟動(dòng)時(shí)會(huì)產(chǎn)生錯(cuò)誤。
如果客戶端是一個(gè)標(biāo)準(zhǔn)的Java應(yīng)用,而非一個(gè)Java Web應(yīng)用,對(duì)于這種類型的應(yīng)用來(lái)說(shuō),為了可以取到服務(wù)端生成的動(dòng)態(tài)Jar文件,我們可以在客戶端Spring的Properties文件中添加一個(gè)名為urule.dynamicJarsRemoteLoadInterval的屬性 來(lái)決定客戶端每隔多久利用客戶端上配置的urule.resporityServerUrl屬性值到服務(wù)端檢查有沒(méi)有新的動(dòng)態(tài)Jar產(chǎn)生,如果有則從服務(wù)端取回并加載。
urule.dynamicJarsRemoteLoadInterval的屬性值單位為分鐘,如果我們?cè)O(shè)置其值為5,那就表示每隔5分鐘到服務(wù)端檢查是否生成新的動(dòng)態(tài)Jar文件,如果不設(shè)置則表示客戶端不會(huì)定期檢查服務(wù)端是否有新的動(dòng)態(tài)Jar包產(chǎn)生。
更多建議: