1、前言
最近遇到个需求,需要弄一个项目的自启动和保活机制。也就是服务器重启后,项目也得跟着启动;当项目无故挂掉后,需要自动启动。该项目为 SpringBoot 项目,部署于 window 服务器,通过创建该项目的服务,以 jar 包方式启动特定名称的进程。
2、自启动方式
目前已存在名为如下图 360rp
的服务,怎么才能让它在服务器启动的时候自动启动呢?
具体创建服务的方式可网上搜索,这里默认已创建成功。
特别注意的是,在创建服务的脚本中,我这里添加了@sc config 360rp start=auto
自启动的脚本,依然没效果,具体啥原因有待研究。
创建 restart-360rp.bat
文件,编写启动服务的命令,后在 window 服务器的自启动目录下加入启动脚本即可。目录如下:C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
启动服务的脚本如下:
@echo on
net start 360rp
3、保活机制
为确保服务或进程无故挂掉导致无法访问的问题。这里的处理方式是定时检测进程是否存在,不存在则启动服务。创建 360rp-heartbeat.bat
文件,具体脚本如下:
如果服务都不存在,则表示在创建服务的过程中有问题了,去处理创建服务的脚本即可。
@echo off
:start
REM 90 秒执行如下代码
choice /t 90 /d y /n >nul
REM 查询 restart-360rp.exe 进程是否存在,0 表示存在,不存在则启动
tasklist|find /i "restart-360rp.exe"
if %errorlevel%==0 (
echo "yes"
) else (
echo "No"
REM 没有则执行上述的启动脚本。
start restart-360rp.bat
)
goto start
后将 360rp-heartbeat.bat 文件放在自启动目录下(C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
)即可。
4、后台运行
在手动停掉 restart-360rp.exe
进程后,90 秒后确实自动启动了,这证明上述脚本已成功,然而,界面上会弹出批处理命令窗口,关掉后则保活机制也就没用了。这不符合现实要求,因此需要在后台执行。在上述脚本前加入如下命令:
@echo off
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("%~nx0 h",0)(window.close)&&exit
:begin
:start
REM 90 秒执行如下代码
choice /t 90 /d y /n >nul
REM 查询 restart-360rp.exe 进程是否存在,0 表示存在,不存在则启动
tasklist|find /i "restart-360rp.exe"
if %errorlevel%==0 (
echo "yes"
) else (
echo "No"
REM 没有则执行上述的启动脚本。/b 表示后台运行
start /b restart-360rp.bat
)
goto start
双击脚本启动后,批处理命令窗口确实不见了,打开任务管理器,已在后台运行。
接着,新的问题又来了。服务器重启后,弹出了批处理窗口执行过程中出错了,如下图所示,说是找不到 360rp-heartbeat.bat
文件
查了一下资料,说是问题在 run("%~nx0 h",0)
上面,window定时任务时,执行的命令是C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\360rp-heartbeat.bat
,执行后再脚本内容%~nx0
参数的值是360rp-heartbeat.bat
,所以mshta vbscript:createobject("wscript.shell").run("%~nx0 h",0)(window.close)&&exit
执行会报错,提示找不到文件,因为这个命令默认的路径是C:\Windows\System32
。
5、进一步完善
知道是路径不对,那么在执行mshta vbscript:createobject("wscript.shell").run("%~nx0 h",0)(window.close)&&exit
命令前,则先跳到C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
路径即可,最终脚本如下:
@echo off
cd C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("%~nx0 h",0)(window.close)&&exit
:begin
:start
REM 90 秒执行如下代码
choice /t 90 /d y /n >nul
REM 查询 restart-360rp.exe 进程是否存在,0 表示存在,不存在则启动
tasklist|find /i "restart-360rp.exe"
if %errorlevel%==0 (
echo "yes"
) else (
echo "No"
REM 没有则执行上述的启动脚本。/b 表示后台运行
start /b restart-360rp.bat
)
goto start
最终得以解决。
6、有待改善
还有一个小问题,若有很多批处理命令在后台执行时,想关闭其中一个批处理程序,但不知道关闭哪一个,因为名称都是一样的,而且执行的位置都是指向C:\Windows\System32
。如下:
所以是否有办法将这个批处理程序的名称更改呢?还有待研究。