基于springboot的自动更新jar

本文介绍了基于Spring Boot的自动更新流程,包括检查更新、下载校验、解密文件和优雅重启。通过对比本地与线上版本号,下载更新文件并进行SHA1校验,最后在系统关闭后进行文件替换和重启,实现无缝更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

	桌面应用很多都能后台自动更新, 而springboot,或者使用tomcat部署,或者jar部署
	要搭建个自动化的发布部署需要很多很复杂,所以有了这个简单的方法来摆脱多服务器的部署需求

自动更新的整个流程

  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分钟检查一下有没有更新
	public void checkUpdata(){
		String res=HttpUtil.get(updateUrl);//updateUrl就是服务器上latest.json
		if(StringUtils.isNotBlank(res)){
			UpdataJson updataJson= JSON.parseObject(res,UpdataJson.class);
			if(updataJson!=null){
				log.error(updataJson.toString());
				Map<String,String> map=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=new File(tmpPath);
				if(tmp.exists()){
					tmp.delete();
				}
				File decryptTmp=new File(decryptFileName);
				if(decryptTmp.exists()){
					decryptTmp.delete();
				}
				//hutool的下载方法,返回的下载文件的大小
				long fileSize=HttpUtil.downloadFile(updataJson.getPackageUrl(),tmpPath);
				if(fileSize!=updataJson.getFileSize()){
					log.error("文件大小不同,下载失败");
				}else{
//对下载好的文件进行解密
					try {
						EncFileUtil.decrypt(tmpPath, decryptFileName, "key");
					} catch (Exception e) {
						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,下面是具体方法

public class AutoUpdataService implements ApplicationContextAware {
	private void restart(){
		String path=getJarPath();
		try {
			Runtime.getRuntime().exec("cmd /k start "+path+"\\updata.bat");
		} catch (IOException e) {
			e.printStackTrace();
		}
		int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
		System.exit(exitCode);
	}
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		context = applicationContext;
	}
	}

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

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

用ping延迟4s,避免文件被占用,导致无法复制。
然后重启完成自动更新。
jar文件的加密可以自己写个小程序,或者参考我这篇,写个maven插件来全自动化处理

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值