基于springboot的自动更新jar


1桌面应用很多都能后台自动更新, 而springboot,或者使用tomcat部署,或者jar部署

2要搭建个自动化的发布部署需要很多很复杂,所以有了这个简单的方法来摆脱多服务器的部署需求

自动更新的整个流程

1.定时检查有没有更新

2.读取本地jar文件中的版本号,和线上版本对比,有更新就开始下载

3.下载后对下载文件进行大小验证,判断是否下载成功

4.对文件进行解密处理

5.校验文件的SHA1是否一直

6.关闭当前系统

7.复制下载好的更新文件到运行目录,重启启动系统

8.完成更新

1.检查更新,对比版本号

我们在打包生成jar时,同时根据打包后的jar的信息,生成一个latest.json

如下

{"fileSize":109225562,"packageUrl":"http://xxx/update/packages","publishTime":"2021-02-22 14:46:10","sha1":"fa3272a2167164e30b6ac9728346392ab1f5ac81","version":"202102220641"}


在里面有更新的主要信息,比如版本号,更新包的下载地址,发布时间,用于校验的文件大小和SHA1

@Scheduled(cron="0 0/10 * * * ?")//每10分钟检查一下有没有更新publicvoidcheckUpdata(){String res=HttpUtil.get(updateUrl);//updateUrl就是服务器上latest.jsonif(StringUtils.isNotBlank(res)){UpdataJson updataJson=JSON.parseObject(res,UpdataJson.class);if(updataJson!=null){log.error(updataJson.toString());Mapmap=jarFileUtils.readJarFile();//这里是从jar文件中读取META-INFO信息log.error("META-INFO内容是="+map.toString());if(map!=null){String nowVersion=map.get("Build-Version");log.error("META-INFO内容是="+map.toString());//对比版本,如果比当前大,就开始更新if(parseLong(updataJson.getVersion())<=parseLong(nowVersion)){log.error("当前版本:"+nowVersion+",已经是最新版本");return;}}else{log.error("读取META-INFO失败");}}}else{log.error("更新文件不存在");}}

2.下载更新,校验和解密文件

//删除历史更新的临时文件File tmp=newFile(tmpPath);if(tmp.exists()){tmp.delete();}File decryptTmp=newFile(decryptFileName);if(decryptTmp.exists()){decryptTmp.delete();}//hutool的下载方法,返回的下载文件的大小longfileSize=HttpUtil.downloadFile(updataJson.getPackageUrl(),tmpPath);if(fileSize!=updataJson.getFileSize()){log.error("文件大小不同,下载失败");}else{//对下载好的文件进行解密try{EncFileUtil.decrypt(tmpPath,decryptFileName,"key");}catch(Exceptione){log.error("文件解密失败");e.printStackTrace();return;}//进行sha1校验,保证不会启动不起来String sha1=getSha1(decryptFileName);if(StringUtils.isNotBlank(sha1)&&sha1.equals(updataJson.getSha1())){log.error("文件下载成功,准备重启");restart();}else{log.error("文件sha1不一致");}}

3.关闭系统,进行重启更新

主要是要优雅的关闭springboot,下面是具体方法

publicclassAutoUpdataServiceimplementsApplicationContextAware{privatevoidrestart(){String path=getJarPath();try{Runtime.getRuntime().exec("cmd /k start "+path+"\\updata.bat");}catch(IOExceptione){e.printStackTrace();}intexitCode=SpringApplication.exit(context,(ExitCodeGenerator)()->0);System.exit(exitCode);}@OverridepublicvoidsetApplicationContext(ApplicationContext applicationContext)throwsBeansException{context=applicationContext;}}

关闭springboot之后,使用runtime调用系统命令对下载好的文件进行复制和重启

bat文件内容如下

@echooff @ping 127.0.0.1-n 4 ©/Y.\package.jar.\package_bak.jar & xcopy/s/e/y.\tmp\dowloadtmp.\package.jar &.\start.bat

用ping延迟4s,避免文件被占用,导致无法复制。

然后重启完成自动更新。

jar文件的加密可以自己写个小程序,或者参考我这篇,写个maven插件来全自动化处理

注:仅个人备注学习,文章来源自转载。

你可能感兴趣的:(基于springboot的自动更新jar)