開發整理-Javaweb應用的系統升級功能
web應用有一個功能菜單是系統升級,通過調用升級腳本,將新發布的war替換原來的tomcat的webapps下的應用,然後停掉tomcate,再重啟tomcate。最初實現就是通過簡單的用在web項目中通過Process調用這個upgrade.sh腳本文件的。
但是這種實現方式出現了一個問題:javaweb應用是tomcate,作為upgrade.sh腳本的父進程,當這個upgrade.sh進程試圖kill掉父進程並重啟的時候,父進程被迫終止後,該子進程也無法繼續執行。所以這種方式實現的升級功能總是失敗。
解決辦法
啟動一個小應用,來執行Shell,那麽這個應用一直以RMI方式監聽來自Java應用的命令,根據相應的命令執行腳本。這樣的話,用這個java進程去調用Shell命令殺死tomcate,並重啟,以此達到系統升級的目的就不會有問題了。
流程如下:
這裏寫圖片描述
升級程序代碼
註冊兩個命令一個完成系統升級,一個完成Javaweb應用重啟,這兩個命令的本質就是調用底層的shell腳本完成相應的功能。
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class ToolkitListener {
public static void main(String[] argv) {
Logger logger =www.jpg521.com Logger.getLogger(ToolkitListener.class);
try {
//初始化log4j
PropertyConfigurator.configure(ClassLoader.getSystemClassLoader().getResource("log4j.properties"));
// 啟動RMI註冊服務,指定端口為1099 (1099為默認端口)
LocateRegistry.createRegistry(1099);
//重啟命令
CmdInterface restartCmd = new CmdOfRestart("restart");
Naming.rebind("restartCmd", restartCmd);
//系統升級命令
CmdInterface upgradeCmd = new CmdOfUpgrade("upgradeCmd");
Naming.rebind("upgradeCmd", upgradeCmd);
logger.info("Sensor ToolkitListener is ready.");
} catch (Exception e) {
logger.error("Sensor ToolkitListener is failed. " , e);
RMI調用
在Javaweb應用中,通過RMI的方式調用對應的對象的腳本執行方法。
public static www.wmyl88.com boolean rmiExecute(www.yuheng119.com/ String name, String var){
if(name==null){
return false;
}
//調用RMI的升級對象完成升級
log.info("rmi object is "+name+",variable is:"+var);
try {
switch(name){
case "upgradeCmd":
CmdInterface cmdOfUpgrade = www.sb45475.com (CmdInterface) Naming.lookup("upgradeCmd");
cmdOfUpgrade.setFileName(var);
cmdOfUpgrade.excuteShell();
return true;
case "restartCmd":
CmdInterface CmdOfRestart = (CmdInterface) Naming.lookup("restartCmd");
CmdOfRestart.excuteShell();
return true;
default :
return true;
}
} catch (MalformedURLException e) {
log.error("RMI調用異常",e);;
} catch (RemoteException e) {
log.error("RMI調用異常",e);;
} catch (NotBoundException e) {
log.error("RMI調用異常",e);;
}
return false;
升級文件校驗
Java web應用提供系統升級功能,由用戶上傳升級包,然後調用腳本完成升級。這個過程中需要對升級包進行校驗,當前系統中維護了當前系統版本號和升級補丁版本號,上傳升級文件中必須提供升級版本的信息,以及上次升級版本號。
web端在啟動升級腳本之前,必須進行升級版本驗證,只有當前系統版本和補丁版本與升級包描述的上次升級版本和上次升級補丁版本一致時,才是正確的升級補丁包,才會執行升級。
註意事項(一)
升級腳本必須有足夠的執行權限才能保證升級腳本能夠正確的被執行,如果是新部署的服務器,可能會出現腳本文件權限不足導致升級執行無效。所以部署項目之後,首先需要修改相關腳本的權限,chmod 777 *給與足夠權限,否則可能會出現升級無效的情況。這種情況下,將後臺執行的shell命令拷貝出來在服務器上執行,很容易看到命令執行失敗的原因是No permmition。
註意事項(二)
RMI註冊的是本地IP和本地默認RMI端口,127.0.0.1:1099,所以/ect/hosts文件對RMI程序會有影響,項目中有一個IP設置的功能,系統初始化之前已經將服務器主機名稱固定了,所以IP修改操作,也必須保證/ect/hosts文件中的主機名稱和127.0.0.1的對應關系,否則IP變更後,RMI根據原來的hosts文件的IP查找主機名稱時由於IP已經修改了,連接超時,導致升級操作無法進行。
解決辦法:IP修改操作的Shell腳本中,完成IP設置後,重置/ect/hosts文件為標準文件,在項目部署的/bin目錄下定義一個standardhosts文件,每次IP設置重啟網卡之前,重置下該文件內容:
#update /etc/hosts
cat /deploy_path/bin/standardhosts>/etc/hosts
1
2
1
2
註意事項(三)
編寫啟動該程序的腳本starttoolkit.sh 內容為Java -jar xxx.jar,保證它跟項目tomcate一起開機啟動,添加到開機啟動項文件tomcat中,以後臺程序的方式啟動:
開發整理-Javaweb應用的系統升級功能