Spring Boot调用 Shell 脚本实现看门狗功能
需要实现看门狗功能,定时检测另外一个程序是否在运行,使用crontab仅可以实现检测程序是否正在运行,无法做到扩展,如:手动重启、程序升级(如果只需要实现自动升级功能可以使用inotify)等功能;最后决定使用SpringBoot调用Shell脚本来实现
一、脚本
1.1启动脚本
#!/bin/bash ps-ef|grep"demo-app-0.0.1-SNAPSHOT.jar"|grep-v"grep" if["$?"-eq0] then #sleep echo$(date"+%Y-%m-%d%H:%M:%S")"processalreadystarted!" else nohupjava-jar-server/project/watchdog/demo-app-0.0.1-SNAPSHOT.jar& echo$(date"+%Y-%m-%d%H:%M:%S")"processhasbeenstarted!" fi
1.2重启脚本
#!/bin/bash
pid=`ps-ef|grep"demo-app-0.0.1-SNAPSHOT.jar"|grep-v"grep"|awk'{print$2}'`
foridin$pid
do
kill-9$id
echo"killed$id"
done
nohupjava-jar-server/project/watchdog/demo-app-0.0.1-SNAPSHOT.jar&
echo$(date"+%Y-%m-%d%H:%M:%S")"processhasbeenrestarted!"
二、功能实现
将脚本放置在程序的资源目录下,每次程序启动时将脚本读取到指定位置,然后再通过定时任务执行脚本
配置内容:
shell:
directory:/project/watchdog
startupFileName:startup.sh
restartFileName:restart.sh
@Configuration
@ConfigurationProperties(prefix="shell")
publicclassShellProperties{
privateStringdirectory;
privateStringstartupFileName;
privateStringrestartFileName;
/*getter&setter*/
publicStringgetFullName(StringfileName){
returndirectory+File.separator+fileName;
}
}
2.1启动时将脚本读取到指定位置
@Component
publicclassInitRunnerimplementsCommandLineRunner{
@Autowired
privateShellPropertiesshellProperties;
@Autowired
ResourceLoaderresourceLoader;
@Override
publicvoidrun(String...args)throwsException{
generateFile(shellProperties.getStartupFileName());
generateFile(shellProperties.getRestartFileName());
}
privatevoidgenerateFile(StringfileName)throwsIOException{
StringfileFullName=shellProperties.getFullName(fileName);
Filefile=newFile(fileFullName);
if(file.exists()){
return;
}
//如果文件已存在,FileWriter会先删除再新建
FileWriterfileWriter=newFileWriter(fileFullName);
Resourceresource=resourceLoader.getResource("classpath:"+fileName);
InputStreaminputStream=resource.getInputStream();
InputStreamReaderinputStreamReader=newInputStreamReader(inputStream);
BufferedReaderbufferedReader=newBufferedReader(inputStreamReader);
Stringdata;
while((data=bufferedReader.readLine())!=null){
fileWriter.write(data+"\n");
}
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
fileWriter.close();
//设置权限,否则会报Permissiondenied
file.setReadable(true);
file.setWritable(true);
file.setExecutable(true);
}
}
2.2定时任务定时任务执行脚本
@Component
publicclassShellTask{
privatestaticfinalLoggerlogger=LoggerFactory.getLogger(ShellTask.class);
@Autowired
privateShellPropertiesshellProperties;
@Scheduled(cron="0/10****?")
publicvoidstart()throwsIOException{
executeShell(shellProperties.getStartupFileName());
}
privatevoidexecuteShell(StringfileName)throwsIOException{
StringfileFullName=shellProperties.getFullName(fileName);
Filefile=newFile(fileFullName);
if(!file.exists()){
logger.error("file{}notexisted!",fileFullName);
return;
}
ProcessBuilderprocessBuilder=newProcessBuilder(fileFullName);
processBuilder.directory(newFile(shellProperties.getDirectory()));
Processprocess=processBuilder.start();
//Stringinput;
//BufferedReaderstdInput=newBufferedReader(newInputStreamReader(process.getInputStream()));
//BufferedReaderstdError=newBufferedReader(newInputStreamReader(process.getErrorStream()));
//while((input=stdInput.readLine())!=null){
//logger.info(input);
//}
//while((input=stdError.readLine())!=null){
//logger.error(input);
//}
intrunningStatus=0;
try{
runningStatus=process.waitFor();
}catch(InterruptedExceptione){
logger.error("shell",e);
}
if(runningStatus!=0){
logger.error("failed.");
}else{
logger.info("success.");
}
}
}
2.3扩展
本例只实现了定时检测程序是否运行,如果没有运行则启动程序;如有需要可以添加接口,调用接口重启程序;或者添加定时任务定时检测程序是否有更新,如果有更新则下载新的jar包然后重启程序
看门狗程序自己可以使用crontab定时检测是否正在运行,模仿上面的启动脚本编写看门狗的启动脚本,然后添加定时任务:
crontab-e */10****/project/watchdog/watchdog.sh sudosystemctlreloadcrond.service
完整代码:GitHub
参考:java去调用并执行shell脚本以及问题总结
总结
到此这篇关于SpringBoot调用Shell脚本实现看门狗功能的文章就介绍到这了,更多相关springboot看门狗内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!