java实现服务器的在线升级更新
本篇文章涉及的知识有
- nginx负载均衡
- bat批量处理文件的编写,bat如何重启一个服务
- java调用bat并执行bat文件
- 文件上传
1.nginx负载均衡
为了实现不断服务,就做到服务端的更新升级,这里考虑到了集群的思想。集群就是部署多台服务器,或者某个模块扩展部署多个服务,达到减轻服务器压力的效果。如部署两台服务,其中一台服务挂调,另一台仍能正常工作。
所以为了实现不断服务更新,这里部署了两台服务器,当更新服务时,先关掉其中一个服务,这个服务更新完毕之后,启动该服务,对另一台服务做同样的操作。
- 这里用到nginx的负载均衡策略,实现两台服务的协同工作,以下为nginx相关的核心配置,这里就使用nginx默认的轮询策略,想要了解更多的负载均衡策略,请查看其他相关资料
upstream test{
server http://127.0.0.1:9005/background weight=1;
server http://127.0.0.1:9006/background down;
}
location /background {
proxy_pass test;
}
2.文件上传更新包
- 前端采用普通文件表单提交
- 后端接收文件
@PostMapping("/update")
public void update(StandardMultipartHttpServletRequest request){
//1.实现文件上传
// 设置更新包安装路径
String path = "D:\\service\\global_info";
//开始上传
try {
Iterator<String> iterator = request.getFileNames();
while (iterator.hasNext()) {
MultipartFile file = request.getFile(iterator.next());
FileCopyUtils.copy(file.getBytes(),new File(path+"//version.zip"));
}
} catch (IOException e) {
e.printStackTrace();
}
}
- spring默认可上传文件大小为1mb,nginx默认文件上传的大小为2mb,大文件的传输须更改相关配置,或者采用断点续传的方法。前者方式application.yml文件和nginx.conf文件的相关配置如下:
- application.yml
spring:
servlet:
multipart:
max-file-size: 400MB
max-request-size: 400MB
- nginx.conf–放到http下,与server同级
client_max_body_size 400m;
3.bat批量处理文件的编写,bat如何重启一个服务
bat文件如下
:获取管理员权限
setlocal EnableDelayedExpansion
color 3e
title 更新版本
PUSHD %~DP0 & cd /d "%~dp0"
%1 %2
mshta vbscript:createobject("shell.application").shellexecute("%~s0","goto :runas","","runas",1)(window.close)&goto :eof
:runas
:切换到当前目录
cd /d %~dp0
set current_path=%cd%
:停止当前服务
net stop Global_info
:获取当前时间
set year=%date:~0,4%
set month=%date:~5,2%
set day=%date:~8,2%
set hour_ten=%time:~0,1%
set hour_one=%time:~1,1%
set minute=%time:~3,2%
set second=%time:~6,2%
:重命名
if "%hour_ten%" == " " (
ren %current_path%\global_info-1.0-SNAPSHOT.jar global_info-1.0-SNAPSHOT%year%%month%%day%0%hour_one%%minute%%second%.jar
) else (
ren %current_path%\global_info-1.0-SNAPSHOT.jar global_info-1.0-SNAPSHOT%year%%month%%day%%hour_ten%%hour_one%%minute%%second%.jar
)
:更新文件
move %current_path%\version\global_info-1.0-SNAPSHOT.jar %current_path%
:%current_path%\7z.exe a %current_path%\global_info-1.0-SNAPSHOT.jar .\version\*
:重新启动服务
net start Global_info
- 上传的更新文件这里为压缩包,批量处理对压缩包进行操作需要相应的压缩软件,7z是一个不错的选择,只需两个文件7z.exe与7z.dll即可使用bat对压缩包进行操作,相关的压缩包bat指令详情请见:
最常用的7-zip命令及使用方法:http://www.pc6.com/edu/53526_5.html
4.java调用bat并执行bat文件
java调用bat文件,及相关的服务器更新如下,这里更新的服务名为Global_info,注意自己服务所在的盘符路径
package com.nlx.controller;
import org.cola.model.Result;
import org.cola.utils.ResultGenerator;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
import java.io.*;
import java.util.Iterator;
/**
* @ClassName: OnlineUpdate
* @Author:Cola.Niu
* @date:2020/2/12 16:05
* @Version:v1.0
* @description:
*/
@RestController
@RequestMapping("/version")
public class OnlineUpdate {
@PostMapping("/update")
public Result update(StandardMultipartHttpServletRequest request){
//1.实现文件上传
// 设置更新包安装路径
String path = "D:\\service\\global_info";
//开始上传
try {
Iterator<String> iterator = request.getFileNames();
while (iterator.hasNext()) {
MultipartFile file = request.getFile(iterator.next());
FileCopyUtils.copy(file.getBytes(),new File(path+"//version.zip"));
}
} catch (IOException e) {
e.printStackTrace();
}
//2.执行解压bat操作,解压完后删除上传的文件
//bat文件中的cmd命令
String cmd = "cd /d %~dp0\n" +
"set current_path=%cd%\n" +
"7z.exe x version.zip -y\n"+
"del version.zip";
//bat文件路径
String batPath = path+"\\version.bat";
FileWriter fw = null;
try {
// 生成bat文件
fw = new FileWriter(batPath);
fw.write(cmd);
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
//执行
executeBat(batPath);
//3.执行更新bat
executeBat(path+"\\update.bat");
return ResultGenerator.returnSuccess();
}
public void executeBat(String batPath){
try {
// 运行bat文件
Process process = Runtime.getRuntime().exec(batPath);
/*InputStream in = process.getInputStream();
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(in));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
in.close();*/
process.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
}
删除服务的方法
- 第一种方法以管理员身份运行cmd ,输入 sc delete 服务名,回车,即可删除对应服务
- 第一种方法如果不成功,原因可能是服务名中有空格等,可用第二种;
win+ R ,输入regedit,即可打开注册表,打开以下目录
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
在目录中找到要删除的服务,删除整个文件夹即可(友情提示别把有用的服务删了)